From a56a3a9c942ea49fd653482f57ab82af97498fb5 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:32:49 -0400 Subject: [PATCH 001/206] add getHatEligibilityModule to IHats interface --- contracts/interfaces/hats/IHats.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index c460c46d..6d486704 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -39,4 +39,5 @@ interface IHats { ) external returns (bool success); function transferHat(uint256 _hatId, address _from, address _to) external; + function getHatEligibilityModule(uint256 _hatId) external view returns (address eligibility); } From 21502f9c5d7c568f3a00d8cc65760cb67d5f7ff9 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:33:18 -0400 Subject: [PATCH 002/206] Add HatsElectionEligibility interface --- .../hats/IHatsElectionEligibility.sol | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 contracts/interfaces/hats/IHatsElectionEligibility.sol diff --git a/contracts/interfaces/hats/IHatsElectionEligibility.sol b/contracts/interfaces/hats/IHatsElectionEligibility.sol new file mode 100644 index 00000000..3b0c7c67 --- /dev/null +++ b/contracts/interfaces/hats/IHatsElectionEligibility.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.13; + +interface IHatsElectionEligibility { + event ElectionOpened(uint128 nextTermEnd); + event ElectionCompleted(uint128 termEnd, address[] winners); + event NewTermStarted(uint128 termEnd); + event Recalled(uint128 termEnd, address[] accounts); + + /// @notice Returns the first second after the current term ends. + /// @dev Also serves as the id for the current term. + function currentTermEnd() external view returns (uint128); + + /// @notice Returns the first second after the next term ends. + /// @dev Also serves as the id for the next term. + function nextTermEnd() external view returns (uint128); + + /// @notice Returns the election status (open or closed) for a given term end. + /// @param termEnd The term end timestamp to query. + function electionStatus( + uint128 termEnd + ) external view returns (bool isElectionOpen); + + /// @notice Returns whether a candidate was elected in a given term. + /// @param termEnd The term end timestamp to query. + /// @param candidate The address of the candidate. + function electionResults( + uint128 termEnd, + address candidate + ) external view returns (bool elected); + + /// @notice Returns the BALLOT_BOX_HAT constant. + function BALLOT_BOX_HAT() external pure returns (uint256); + + /// @notice Returns the ADMIN_HAT constant. + function ADMIN_HAT() external pure returns (uint256); + + /** + * @notice Submit the results of an election for a specified term. + * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT. + * @param _termEnd The id of the term for which the election results are being submitted. + * @param _winners The addresses of the winners of the election. + */ + function elect(uint128 _termEnd, address[] calldata _winners) external; + + /** + * @notice Submit the results of a recall election for a specified term. + * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT. + * @param _termEnd The id of the term for which the recall results are being submitted. + * @param _recallees The addresses to be recalled. + */ + function recall(uint128 _termEnd, address[] calldata _recallees) external; + + /** + * @notice Set the next term and open the election for it. + * @dev Only callable by the wearer(s) of the ADMIN_HAT. + * @param _newTermEnd The id of the term that will be opened. + */ + function setNextTerm(uint128 _newTermEnd) external; + + /** + * @notice Start the next term, updating the current term. + * @dev Can be called by anyone, but will revert if conditions are not met. + */ + function startNextTerm() external; + + /** + * @notice Determine the eligibility and standing of a wearer for a hat. + * @param _wearer The address of the hat wearer. + * @param _hatId The ID of the hat. + * @return eligible True if the wearer is eligible for the hat. + * @return standing True if the wearer is in good standing. + */ + function getWearerStatus( + address _wearer, + uint256 _hatId + ) external view returns (bool eligible, bool standing); +} From e69292e2889ce09817d832c573a5e27cbded82a9 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:34:37 -0400 Subject: [PATCH 003/206] wip DecentAutonomousAdminHat contract --- contracts/DecentAutonomousAdminHat.sol | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 contracts/DecentAutonomousAdminHat.sol diff --git a/contracts/DecentAutonomousAdminHat.sol b/contracts/DecentAutonomousAdminHat.sol new file mode 100644 index 00000000..8e375630 --- /dev/null +++ b/contracts/DecentAutonomousAdminHat.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: MIT +pragma solidity =0.8.19; +import "./interfaces/hats/IHats.sol"; +import "./interfaces/hats/IHatsElectionEligibility.sol"; + +contract DecentAutonomousAdminHat { + string public constant NAME = "DecentAutonomousAdminHat"; + + uint256 public hatId; + + struct TriggerStartArgs { + address userHatSmartAccountAddress; + IHats userHatPropocol; + uint256 userHatId; + } + + // ////////////////////////////////////////////////////////////// + // Constructor + // ////////////////////////////////////////////////////////////// + constructor() {} + + // ////////////////////////////////////////////////////////////// + // Initializer + // ////////////////////////////////////////////////////////////// + + /** + * + * @param _initData encoded initialization parameters: `uint256 hatId` + */ + + function _setup(bytes calldata _initData) internal { + (hatId) = abi.decode(_initData, (uint256)); + } + + // ////////////////////////////////////////////////////////////// + // Public Functions + // ////////////////////////////////////////////////////////////// + function triggerStartNextTerm(TriggerStartArgs calldata args) public { + // ? should we use `checkHatWearerStatus` here? + // ? should we use `isAdminOfHat` here? + // ? should we use `isEligible` here? + + address hatsEE = args.userHatPropocol.getHatEligibilityModule( + args.userHatId + ); + + IHatsElectionEligibility(hatsEE).startNextTerm(); + } + + // ////////////////////////////////////////////////////////////// + // Internal Functions + // ////////////////////////////////////////////////////////////// +} From 9e66612791035f746e344fce1e3ea551f90e1f5e Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:36:08 -0400 Subject: [PATCH 004/206] create AA Hat --- contracts/DecentAutonomousAdminHat.sol | 123 ++++++++++++++++++++----- 1 file changed, 102 insertions(+), 21 deletions(-) diff --git a/contracts/DecentAutonomousAdminHat.sol b/contracts/DecentAutonomousAdminHat.sol index 8e375630..407b1a4c 100644 --- a/contracts/DecentAutonomousAdminHat.sol +++ b/contracts/DecentAutonomousAdminHat.sol @@ -2,52 +2,133 @@ pragma solidity =0.8.19; import "./interfaces/hats/IHats.sol"; import "./interfaces/hats/IHatsElectionEligibility.sol"; +import "./interfaces/sablier/ISablierV2LockupLinear.sol"; contract DecentAutonomousAdminHat { string public constant NAME = "DecentAutonomousAdminHat"; - uint256 public hatId; + uint256 public adminHatId; + struct SablierStreamInfo { + uint256 streamId; + ISablierV2LockupLinear sablierV2LockupLinear; + } struct TriggerStartArgs { address userHatSmartAccountAddress; - IHats userHatPropocol; + address currentWearer; + IHats userHatProtocol; uint256 userHatId; + address nominatedWearer; + SablierStreamInfo[] sablierStreamInfo; } // ////////////////////////////////////////////////////////////// // Constructor // ////////////////////////////////////////////////////////////// - constructor() {} - - // ////////////////////////////////////////////////////////////// - // Initializer - // ////////////////////////////////////////////////////////////// - - /** - * - * @param _initData encoded initialization parameters: `uint256 hatId` - */ - - function _setup(bytes calldata _initData) internal { - (hatId) = abi.decode(_initData, (uint256)); + constructor(uint256 _adminHatId) { + adminHatId =_adminHatId; } // ////////////////////////////////////////////////////////////// // Public Functions // ////////////////////////////////////////////////////////////// function triggerStartNextTerm(TriggerStartArgs calldata args) public { - // ? should we use `checkHatWearerStatus` here? - // ? should we use `isAdminOfHat` here? - // ? should we use `isEligible` here? + require( + args.userHatProtocol.isWearerOfHat( + args.currentWearer, + args.userHatId + ), + "Not current wearer" + ); + + address hatsEligibilityModuleAddress = args + .userHatProtocol + .getHatEligibilityModule(args.userHatId); + + IHatsElectionEligibility hatsElectionModule = IHatsElectionEligibility( + hatsEligibilityModuleAddress + ); + + hatsElectionModule.startNextTerm(); + + // transfer user hat to self + args.userHatProtocol.transferHat( + args.userHatId, + args.currentWearer, + address(this) + ); - address hatsEE = args.userHatPropocol.getHatEligibilityModule( - args.userHatId + // for each withdrawable stream, withdraw funds to current wearer of hat + _flushUnclaimedFunds( + _getStreamsWithUnclaimedFunds(args.sablierStreamInfo), + args.currentWearer ); - IHatsElectionEligibility(hatsEE).startNextTerm(); + // transfer hat to nominated wearer + args.userHatProtocol.transferHat( + args.userHatId, + address(this), + args.nominatedWearer + ); } // ////////////////////////////////////////////////////////////// // Internal Functions // ////////////////////////////////////////////////////////////// + + /** + * @dev Withdraws unclaimed funds from Sablier streams. + * @param _sablierStreamInfo SablierStreamInfo array + */ + function _flushUnclaimedFunds( + SablierStreamInfo[] memory _sablierStreamInfo, + address withdrawTo + ) internal { + for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { + _sablierStreamInfo[i].sablierV2LockupLinear.withdrawMax( + _sablierStreamInfo[i].streamId, + withdrawTo + ); + } + } + + /** + * @dev Returns an array of Sablier stream ids that have unclaimed funds. + * @param _sablierStreamInfo SablierStreamInfo array + * @return streamsWithUnclaimedFunds An array of SablierStreamInfo that have unclaimed funds + */ + function _getStreamsWithUnclaimedFunds( + SablierStreamInfo[] memory _sablierStreamInfo + ) internal view returns (SablierStreamInfo[] memory) { + uint256 streamsWithUnclaimedFundsCount = 0; + + for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { + uint128 withdrawableAmount = _sablierStreamInfo[i] + .sablierV2LockupLinear + .withdrawableAmountOf(_sablierStreamInfo[i].streamId); + + if (withdrawableAmount > 0) { + streamsWithUnclaimedFundsCount++; + } + } + + SablierStreamInfo[] + memory streamsWithUnclaimedFunds = new SablierStreamInfo[]( + streamsWithUnclaimedFundsCount + ); + uint256 index = 0; + + for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { + uint128 withdrawableAmount = _sablierStreamInfo[i] + .sablierV2LockupLinear + .withdrawableAmountOf(_sablierStreamInfo[i].streamId); + + if (withdrawableAmount > 0) { + streamsWithUnclaimedFunds[index] = _sablierStreamInfo[i]; + index++; + } + } + + return streamsWithUnclaimedFunds; + } } From 44324411ed700fafbd98a597d635e95ba41383cc Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 03:45:00 -0400 Subject: [PATCH 005/206] remove unused param --- contracts/DecentAutonomousAdminHat.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/DecentAutonomousAdminHat.sol b/contracts/DecentAutonomousAdminHat.sol index 407b1a4c..05901467 100644 --- a/contracts/DecentAutonomousAdminHat.sol +++ b/contracts/DecentAutonomousAdminHat.sol @@ -14,7 +14,6 @@ contract DecentAutonomousAdminHat { ISablierV2LockupLinear sablierV2LockupLinear; } struct TriggerStartArgs { - address userHatSmartAccountAddress; address currentWearer; IHats userHatProtocol; uint256 userHatId; @@ -26,7 +25,7 @@ contract DecentAutonomousAdminHat { // Constructor // ////////////////////////////////////////////////////////////// constructor(uint256 _adminHatId) { - adminHatId =_adminHatId; + adminHatId = _adminHatId; } // ////////////////////////////////////////////////////////////// @@ -40,7 +39,6 @@ contract DecentAutonomousAdminHat { ), "Not current wearer" ); - address hatsEligibilityModuleAddress = args .userHatProtocol .getHatEligibilityModule(args.userHatId); From 5830d1f68f35b5e17cfac81dde6081a0fee5c908 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 03:46:11 -0400 Subject: [PATCH 006/206] update interfaces with needed methods --- contracts/interfaces/hats/IHats.sol | 10 +++++- .../sablier/ISablierV2LockupLinear.sol | 31 +++++++++++++++++++ contracts/mocks/MockHats.sol | 9 ++++++ contracts/mocks/MockSablierV2LockupLinear.sol | 13 ++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index 6d486704..3a3743ea 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -39,5 +39,13 @@ interface IHats { ) external returns (bool success); function transferHat(uint256 _hatId, address _from, address _to) external; - function getHatEligibilityModule(uint256 _hatId) external view returns (address eligibility); + + function getHatEligibilityModule( + uint256 _hatId + ) external view returns (address eligibility); + + function isWearerOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isWearer); } diff --git a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol index 0aa6cac9..4bf0c724 100644 --- a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol +++ b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol @@ -8,4 +8,35 @@ interface ISablierV2LockupLinear { function createWithTimestamps( LockupLinear.CreateWithTimestamps calldata params ) external returns (uint256 streamId); + + /// @notice Emitted when assets are withdrawn from a stream. + /// @param streamId The ID of the stream. + /// @param to The address that has received the withdrawn assets. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals. + event WithdrawFromLockupStream(uint256 indexed streamId, address indexed to, IERC20 indexed asset, uint128 amount); + + /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`. + /// + /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - Refer to the notes in {withdraw}. + /// + /// Requirements: + /// - Refer to the requirements in {withdraw}. + /// + /// @param streamId The ID of the stream to withdraw from. + /// @param to The address receiving the withdrawn assets. + /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals. + function withdrawMax( + uint256 streamId, + address to + ) external returns (uint128 withdrawnAmount); + + /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's + /// decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function withdrawableAmountOf(uint256 streamId) external view returns (uint128 withdrawableAmount); } diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index f5ac2ece..1cf74405 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -33,4 +33,13 @@ contract MockHats is IHats { } function transferHat(uint256, address, address) external {} + + function getHatEligibilityModule( + uint256 _hatId + ) external view returns (address eligibility) {} + + function isWearerOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isWearer) {} } diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 7d737bb4..8511d364 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -156,4 +156,17 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { stream.recipient = recipient; } + + function withdrawMax( + uint256 streamId, + address to + ) external override returns (uint128 withdrawnAmount) { + withdrawnAmount = withdrawableAmountOf(streamId); + require(withdrawnAmount > 0, "No withdrawable amount"); + + Stream storage stream = streams[streamId]; + stream.totalAmount -= withdrawnAmount; + IERC20(stream.asset).transfer(to, withdrawnAmount); + emit WithdrawFromLockupStream(streamId, to, IERC20(stream.asset), withdrawnAmount); + } } From 5f8828591c61c1f3ab3145c52bb53e7f3684860a Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 03:47:11 -0400 Subject: [PATCH 007/206] add tests for Wearer requirement --- contracts/mocks/MockHatsAdmin.sol | 77 +++++++++++++ .../mocks/MockHatsElectionEligibility.sol | 41 +++++++ test/DecentAutonomousAdminHat.test.ts | 108 ++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 contracts/mocks/MockHatsAdmin.sol create mode 100644 contracts/mocks/MockHatsElectionEligibility.sol create mode 100644 test/DecentAutonomousAdminHat.test.ts diff --git a/contracts/mocks/MockHatsAdmin.sol b/contracts/mocks/MockHatsAdmin.sol new file mode 100644 index 00000000..5b7fef2c --- /dev/null +++ b/contracts/mocks/MockHatsAdmin.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity =0.8.19; + +import "../interfaces/hats/IHats.sol"; + +contract MockHatsAutoAdmin is IHats { + uint256 hatId = 0; + mapping(uint256 => address) public wearer; + mapping(uint256 => address) public eligibility; + + event HatCreated(uint256 hatId); + + function mintTopHat( + address _target, + string memory _details, + string memory _imageURI + ) external pure returns (uint256 topHatId) { + // Silence unused variable warnings + _target; + _details; + _imageURI; + return 0; + } + + function createHat( + uint256 _admin, + string calldata _details, + uint32 _maxSupply, + address _eligibility, + address _toggle, + bool _mutable, + string calldata _imageURI + ) external returns (uint256 newHatId) { + // Silence unused variable warnings + _admin; + _details; + _maxSupply; + _toggle; + _mutable; + _imageURI; + hatId++; + eligibility[hatId] = _eligibility; + emit HatCreated(hatId); + return hatId; + } + + function mintHat( + uint256 _hatId, + address _wearer + ) external returns (bool success) { + wearer[_hatId] = _wearer; + return true; + } + + function isWearerOfHat( + address _wearer, + uint256 _hatId + ) external view override returns (bool) { + return _wearer == wearer[_hatId]; + } + + function getHatEligibilityModule( + uint256 _hatId + ) external view override returns (address) { + return eligibility[_hatId]; + } + + function transferHat( + uint256 _hatId, + address from, + address to + ) external override { + // Silence unused variable warnings + from; + wearer[_hatId] = to; + } +} diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionEligibility.sol new file mode 100644 index 00000000..d9d8daab --- /dev/null +++ b/contracts/mocks/MockHatsElectionEligibility.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +contract MockHatsElectionEligibility { + uint128 private _currentTermEnd; + uint128 private _nextTermEnd; + mapping(uint128 => bool) private _electionStatus; + + event ElectionOpened(uint128 nextTermEnd); + event ElectionCompleted(uint128 termEnd, address[] winners); + event NewTermStarted(uint128 termEnd); + + // Mock function to simulate starting the next term + function startNextTerm() external { + _currentTermEnd = _nextTermEnd; + _nextTermEnd = 0; + + emit NewTermStarted(_currentTermEnd); + } + + function currentTermEnd() external view returns (uint128) { + return _currentTermEnd; + } + + function electionStatus(uint128 termEnd) external view returns (bool) { + return _electionStatus[termEnd]; + } + + // Functions to set the mock data for testing + function setCurrentTermEnd(uint128 termEnd) external { + _currentTermEnd = termEnd; + } + + function setNextTermEnd(uint128 termEnd) external { + _nextTermEnd = termEnd; + } + + function setElectionStatus(uint128 termEnd, bool status) external { + _electionStatus[termEnd] = status; + } +} diff --git a/test/DecentAutonomousAdminHat.test.ts b/test/DecentAutonomousAdminHat.test.ts new file mode 100644 index 00000000..a84934b9 --- /dev/null +++ b/test/DecentAutonomousAdminHat.test.ts @@ -0,0 +1,108 @@ +import { + DecentAutonomousAdminHat, + DecentAutonomousAdminHat__factory, + MockHatsAutoAdmin, + MockHatsAutoAdmin__factory, + MockHatsElectionEligibility, + MockHatsElectionEligibility__factory, +} from "../typechain-types" +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" +import { expect } from "chai" +import hre from "hardhat" + +describe.only("DecentAutonomousAdminHat", function () { + // Signer accounts + let deployer: SignerWithAddress + let currentWearer: SignerWithAddress + let randomUser: SignerWithAddress + let adminHatWearer: SignerWithAddress + let nominatedWearer: SignerWithAddress + + // Contract instances + let hatsProtocol: MockHatsAutoAdmin + let hatsElectionModule: MockHatsElectionEligibility + let adminHat: DecentAutonomousAdminHat + + // Variables + let userHatId: bigint + + beforeEach(async function () { + // Get signers + ;[deployer, adminHatWearer, currentWearer, nominatedWearer, randomUser] = + await hre.ethers.getSigners() + + // Deploy MockHatsAutoAdmin (Mock Hats Protocol) + hatsProtocol = await new MockHatsAutoAdmin__factory(deployer).deploy() + + // Deploy MockHatsElectionEligibility (Eligibility Module) + hatsElectionModule = await new MockHatsElectionEligibility__factory(deployer).deploy() + + // Create Admin Hat + const createAdminTx = await hatsProtocol.createHat( + await hatsProtocol.getAddress(), // Admin address (self-administered) + "Details", // Hat details + 100, // Max supply + hre.ethers.ZeroAddress, // Eligibility module (none) + hre.ethers.ZeroAddress, // Toggle module (none) + true, // Is mutable + "imageURI" // Image URI + ) + const createAdminTxReceipt = await createAdminTx.wait() + const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0] + + // Deploy DecentAutonomousAdminHat contract with the admin hat ID + adminHat = await new DecentAutonomousAdminHat__factory(deployer).deploy(adminHatId) + + // Mint the admin hat to adminHatWearer + await hatsProtocol.mintHat(adminHatId, await adminHatWearer.getAddress()) + + // Create User Hat under the admin hat + const createUserTx = await hatsProtocol.createHat( + await adminHat.getAddress(), // Admin address (adminHat contract) + "Details", // Hat details + 100, // Max supply + await hatsElectionModule.getAddress(), // Eligibility module (election module) + hre.ethers.ZeroAddress, // Toggle module (none) + false, // Is mutable + "imageURI" // Image URI + ) + + const createUserTxReceipt = await createUserTx.wait() + userHatId = createUserTxReceipt?.toJSON().logs[0].args[0] + + // Mint the user hat to currentWearer + await hatsProtocol.mintHat(userHatId, await currentWearer.getAddress()) + }) + + describe("triggerStartNextTerm", function () { + it("should correctly validate current wearer and transfer", async function () { + const args = { + currentWearer: currentWearer.address, + userHatProtocol: await hatsProtocol.getAddress(), + userHatId: userHatId, + nominatedWearer: nominatedWearer.address, + sablierStreamInfo: [], // No Sablier stream info for this test + } + + // Call triggerStartNextTerm on the adminHat contract + await adminHat.triggerStartNextTerm(args) + + // Verify the hat is now worn by the nominated wearer + expect(await hatsProtocol.isWearerOfHat(nominatedWearer.address, userHatId)).to.be.true + }) + it("should correctly invalidate random address as current wearer", async function () { + const args = { + currentWearer: randomUser.address, + userHatProtocol: await hatsProtocol.getAddress(), + userHatId: userHatId, + nominatedWearer: nominatedWearer.address, + sablierStreamInfo: [], // No Sablier stream info for this test + } + + // Verify the hat is now worn by the current wearer + await expect(adminHat.connect(randomUser).triggerStartNextTerm(args)).to.be.revertedWith( + "Not current wearer" + ) + }) + }) +}) From 92456962eb09a1c5493af6d7613d6ebeb80fe8d9 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 03:47:19 -0400 Subject: [PATCH 008/206] add deployment file --- deploy/core/018_deploy_DecentAutonomousAdminHat.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 deploy/core/018_deploy_DecentAutonomousAdminHat.ts diff --git a/deploy/core/018_deploy_DecentAutonomousAdminHat.ts b/deploy/core/018_deploy_DecentAutonomousAdminHat.ts new file mode 100644 index 00000000..b2862578 --- /dev/null +++ b/deploy/core/018_deploy_DecentAutonomousAdminHat.ts @@ -0,0 +1,9 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + await deployNonUpgradeable(hre, "DecentAutonomousAdminHat"); +}; + +export default func; From 77e81dbf524d1d2949383b075206a31af8723aa9 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 04:07:35 -0400 Subject: [PATCH 009/206] drop hat off name --- ...DecentAutonomousAdminHat.sol => DecentAutonomousAdmin.sol} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename contracts/{DecentAutonomousAdminHat.sol => DecentAutonomousAdmin.sol} (97%) diff --git a/contracts/DecentAutonomousAdminHat.sol b/contracts/DecentAutonomousAdmin.sol similarity index 97% rename from contracts/DecentAutonomousAdminHat.sol rename to contracts/DecentAutonomousAdmin.sol index 05901467..31760c3b 100644 --- a/contracts/DecentAutonomousAdminHat.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -4,8 +4,8 @@ import "./interfaces/hats/IHats.sol"; import "./interfaces/hats/IHatsElectionEligibility.sol"; import "./interfaces/sablier/ISablierV2LockupLinear.sol"; -contract DecentAutonomousAdminHat { - string public constant NAME = "DecentAutonomousAdminHat"; +contract DecentAutonomousAdmin { + string public constant NAME = "DecentAutonomousAdmin"; uint256 public adminHatId; From 85b82178f43077c5d47939545ae13efcc8a51ac2 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 04:45:58 -0400 Subject: [PATCH 010/206] add Autonomous Admin as wearer of admin hat - break out create method into seperate function --- contracts/DecentHats_0_1_0.sol | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index c00dadaa..9f79455a 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -9,6 +9,7 @@ import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/IHats.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; +import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; contract DecentHats_0_1_0 { string public constant NAME = "DecentHats_0_1_0"; @@ -205,6 +206,30 @@ contract DecentHats_0_1_0 { } } + function createAdminHatAndAccount( + IHats hatsProtocol, + uint256 adminHatId, + Hat calldata hat, + address topHatAccount, + IERC6551Registry registry, + address hatsAccountImplementation, + bytes32 salt + ) internal returns (uint256 hatId, address accountAddress) { + hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); + + accountAddress = createAccount( + registry, + hatsAccountImplementation, + salt, + address(hatsProtocol), + hatId + ); + + // Set the Autonomous Admin as the wearer of the admin hat + DecentAutonomousAdmin adminHat = new DecentAutonomousAdmin(adminHatId); + hatsProtocol.mintHat(hatId, address(adminHat)); + } + function createAndDeclareTree(CreateTreeParams calldata params) public { bytes32 salt = getSalt(); @@ -219,7 +244,7 @@ contract DecentHats_0_1_0 { updateKeyValuePairs(params.keyValuePairs, topHatId); - (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams( + (uint256 adminHatId, ) = createAdminHatAndAccount( params.hatsProtocol, topHatId, params.adminHat, From 8666ac5957115692f705437b4d617cfd465cbabf Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 04:46:38 -0400 Subject: [PATCH 011/206] remove only --- test/DecentAutonomousAdminHat.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DecentAutonomousAdminHat.test.ts b/test/DecentAutonomousAdminHat.test.ts index a84934b9..5d8c7b45 100644 --- a/test/DecentAutonomousAdminHat.test.ts +++ b/test/DecentAutonomousAdminHat.test.ts @@ -10,7 +10,7 @@ import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" import hre from "hardhat" -describe.only("DecentAutonomousAdminHat", function () { +describe("DecentAutonomousAdminHat", function () { // Signer accounts let deployer: SignerWithAddress let currentWearer: SignerWithAddress From db60757cc32d5859e67e278584934eee9a5e320b Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 05:17:18 -0400 Subject: [PATCH 012/206] fix deploy name --- deploy/core/018_deploy_DecentAutonomousAdminHat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/core/018_deploy_DecentAutonomousAdminHat.ts b/deploy/core/018_deploy_DecentAutonomousAdminHat.ts index b2862578..f1adb696 100644 --- a/deploy/core/018_deploy_DecentAutonomousAdminHat.ts +++ b/deploy/core/018_deploy_DecentAutonomousAdminHat.ts @@ -3,7 +3,7 @@ import { DeployFunction } from "hardhat-deploy/types"; import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentAutonomousAdminHat"); + await deployNonUpgradeable(hre, "DecentAutonomousAdmin"); }; export default func; From 6b2d609b9184e86917e085effbc57d82fddc6577 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 25 Sep 2024 23:21:36 -0400 Subject: [PATCH 013/206] pass eligibility address as param --- contracts/DecentHats_0_1_0.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index 9f79455a..bfbf2e74 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -29,6 +29,7 @@ contract DecentHats_0_1_0 { uint32 maxSupply; string details; string imageURI; + address eligibility; bool isMutable; address wearer; SablierStreamParams[] sablierParams; // Optional Sablier stream parameters @@ -93,7 +94,7 @@ contract DecentHats_0_1_0 { _hat.details, _hat.maxSupply, topHatAccount, - topHatAccount, + _hat.eligibility, _hat.isMutable, _hat.imageURI ); From b53a417ebea667cb249c8d3d34b6c730f5c58ed0 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:50:54 -0400 Subject: [PATCH 014/206] update with proxy pattern --- contracts/DecentAutonomousAdmin.sol | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 31760c3b..d6aef8be 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -6,7 +6,7 @@ import "./interfaces/sablier/ISablierV2LockupLinear.sol"; contract DecentAutonomousAdmin { string public constant NAME = "DecentAutonomousAdmin"; - + string public version_; uint256 public adminHatId; struct SablierStreamInfo { @@ -24,7 +24,14 @@ contract DecentAutonomousAdmin { // ////////////////////////////////////////////////////////////// // Constructor // ////////////////////////////////////////////////////////////// - constructor(uint256 _adminHatId) { + constructor(string memory _version) { + version_ = _version; + } + + // ////////////////////////////////////////////////////////////// + // Initializer + // ////////////////////////////////////////////////////////////// + function setUp(uint256 _adminHatId) public { adminHatId = _adminHatId; } From 4170355359500f09b88ba7932205a493f82b57f1 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:51:10 -0400 Subject: [PATCH 015/206] update with new props to deploy proxy --- contracts/DecentHats_0_1_0.sol | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index bfbf2e74..b8ed2a75 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -10,6 +10,7 @@ import {IHats} from "./interfaces/hats/IHats.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; +import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; contract DecentHats_0_1_0 { string public constant NAME = "DecentHats_0_1_0"; @@ -38,6 +39,8 @@ contract DecentHats_0_1_0 { struct CreateTreeParams { IHats hatsProtocol; address hatsAccountImplementation; + ModuleProxyFactory moduleProxyFactory; + address decentAutonomousAdminMasterCopy; IERC6551Registry registry; address keyValuePairs; string topHatDetails; @@ -214,7 +217,9 @@ contract DecentHats_0_1_0 { address topHatAccount, IERC6551Registry registry, address hatsAccountImplementation, - bytes32 salt + bytes32 salt, + ModuleProxyFactory moduleProxyFactory, + address decentAutonomousAdminMasterCopy ) internal returns (uint256 hatId, address accountAddress) { hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); @@ -226,9 +231,21 @@ contract DecentHats_0_1_0 { hatId ); - // Set the Autonomous Admin as the wearer of the admin hat - DecentAutonomousAdmin adminHat = new DecentAutonomousAdmin(adminHatId); - hatsProtocol.mintHat(hatId, address(adminHat)); + bytes memory initializer = abi.encodeWithSignature( + "setUp(uint256)", + adminHatId + ); + uint256 saltNonce = uint256( + keccak256(abi.encodePacked(block.timestamp, initializer)) + ); + hatsProtocol.mintHat( + hatId, + moduleProxyFactory.deployModule( + decentAutonomousAdminMasterCopy, + initializer, + saltNonce + ) + ); } function createAndDeclareTree(CreateTreeParams calldata params) public { @@ -252,7 +269,9 @@ contract DecentHats_0_1_0 { topHatAccount, params.registry, params.hatsAccountImplementation, - salt + salt, + params.moduleProxyFactory, + params.decentAutonomousAdminMasterCopy ); for (uint256 i = 0; i < params.hats.length; ) { From 5094eef96731721cf2c471270423a557b4ee5b7f Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:52:02 -0400 Subject: [PATCH 016/206] rename and update tests to support proxy pattern --- ....test.ts => DecentAutonomousAdmin.test.ts} | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) rename test/{DecentAutonomousAdminHat.test.ts => DecentAutonomousAdmin.test.ts} (75%) diff --git a/test/DecentAutonomousAdminHat.test.ts b/test/DecentAutonomousAdmin.test.ts similarity index 75% rename from test/DecentAutonomousAdminHat.test.ts rename to test/DecentAutonomousAdmin.test.ts index 5d8c7b45..c4f9e45f 100644 --- a/test/DecentAutonomousAdminHat.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -1,36 +1,40 @@ +import { ModuleProxyFactory } from "../typechain-types/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory" import { - DecentAutonomousAdminHat, - DecentAutonomousAdminHat__factory, + DecentAutonomousAdmin, + DecentAutonomousAdmin__factory, MockHatsAutoAdmin, MockHatsAutoAdmin__factory, MockHatsElectionEligibility, MockHatsElectionEligibility__factory, + ModuleProxyFactory__factory, } from "../typechain-types" import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" import hre from "hardhat" -describe("DecentAutonomousAdminHat", function () { +describe.only("DecentAutonomousAdminHat", function () { // Signer accounts let deployer: SignerWithAddress let currentWearer: SignerWithAddress let randomUser: SignerWithAddress - let adminHatWearer: SignerWithAddress let nominatedWearer: SignerWithAddress // Contract instances let hatsProtocol: MockHatsAutoAdmin let hatsElectionModule: MockHatsElectionEligibility - let adminHat: DecentAutonomousAdminHat + let adminHat: DecentAutonomousAdmin + let adminHatMasterCopy: DecentAutonomousAdmin + let moduleProxyFactory: ModuleProxyFactory // Variables let userHatId: bigint beforeEach(async function () { // Get signers - ;[deployer, adminHatWearer, currentWearer, nominatedWearer, randomUser] = + ;[deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners() + moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() // Deploy MockHatsAutoAdmin (Mock Hats Protocol) hatsProtocol = await new MockHatsAutoAdmin__factory(deployer).deploy() @@ -51,14 +55,23 @@ describe("DecentAutonomousAdminHat", function () { const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0] // Deploy DecentAutonomousAdminHat contract with the admin hat ID - adminHat = await new DecentAutonomousAdminHat__factory(deployer).deploy(adminHatId) + adminHatMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy("TEST") + const proxyDeployTx = await moduleProxyFactory.deployModule( + await adminHatMasterCopy.getAddress(), + adminHatMasterCopy.interface.encodeFunctionData("setUp", [adminHatId]), + 1n + ) + const proxyDeployTxReceipt = await proxyDeployTx.wait() + const proxyAddress = await proxyDeployTxReceipt?.toJSON().logs[0].args[0] + + adminHat = DecentAutonomousAdmin__factory.connect(proxyAddress, deployer) // Mint the admin hat to adminHatWearer - await hatsProtocol.mintHat(adminHatId, await adminHatWearer.getAddress()) + await hatsProtocol.mintHat(adminHatId, proxyAddress) // Create User Hat under the admin hat const createUserTx = await hatsProtocol.createHat( - await adminHat.getAddress(), // Admin address (adminHat contract) + proxyAddress, // Admin address (adminHat contract) "Details", // Hat details 100, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) From ca71da099ba29d9be4cf60ff60dedd1b787eed14 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 02:16:19 -0400 Subject: [PATCH 017/206] remove only --- test/DecentAutonomousAdmin.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index c4f9e45f..68fc2ec3 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -12,7 +12,7 @@ import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" import hre from "hardhat" -describe.only("DecentAutonomousAdminHat", function () { +describe("DecentAutonomousAdminHat", function () { // Signer accounts let deployer: SignerWithAddress let currentWearer: SignerWithAddress From 94d0cf47d5c83f7625ebf5ca33d7bf69fa720f3d Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 02:16:34 -0400 Subject: [PATCH 018/206] update DecentHats tests to support changes to contract --- test/DecentHats_0_1_0.test.ts | 736 +++++++++++++++++----------------- 1 file changed, 358 insertions(+), 378 deletions(-) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index afaa5c95..f1741567 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -15,23 +15,22 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, -} from "../typechain-types"; + DecentAutonomousAdmin__factory, + ModuleProxyFactory__factory, +} from "../typechain-types" -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers, solidityPackedKeccak256 } from "ethers"; -import hre from "hardhat"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" +import { expect } from "chai" +import { ethers, solidityPackedKeccak256 } from "ethers" +import hre from "hardhat" -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, -} from "./GlobalSafeDeployments.test"; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test" import { buildSafeTransaction, buildSignatureBytes, predictGnosisSafeAddress, safeSignTypedData, -} from "./helpers"; +} from "./helpers" const executeSafeTransaction = async ({ safe, @@ -39,20 +38,20 @@ const executeSafeTransaction = async ({ transactionData, signers, }: { - safe: GnosisSafeL2; - to: string; - transactionData: string; - signers: SignerWithAddress[]; + safe: GnosisSafeL2 + to: string + transactionData: string + signers: SignerWithAddress[] }) => { const safeTx = buildSafeTransaction({ to, data: transactionData, nonce: await safe.nonce(), - }); + }) const sigs = await Promise.all( signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx)) - ); + ) const tx = await safe.execTransaction( safeTx.to, @@ -65,59 +64,64 @@ const executeSafeTransaction = async ({ safeTx.gasToken, safeTx.refundReceiver, buildSignatureBytes(sigs) - ); + ) + + return tx +} - return tx; -}; +describe.only("DecentHats_0_1_0", () => { + let dao: SignerWithAddress -describe("DecentHats_0_1_0", () => { - let dao: SignerWithAddress; + let mockHats: MockHats + let mockHatsAddress: string - let mockHats: MockHats; - let mockHatsAddress: string; + let keyValuePairs: KeyValuePairs + let gnosisSafe: GnosisSafeL2 - let keyValuePairs: KeyValuePairs; - let gnosisSafe: GnosisSafeL2; + let decentHats: DecentHats_0_1_0 + let decentHatsAddress: string - let decentHats: DecentHats_0_1_0; - let decentHatsAddress: string; + let gnosisSafeAddress: string + let erc6551Registry: ERC6551Registry - let gnosisSafeAddress: string; - let erc6551Registry: ERC6551Registry; + let adminHatMasterCopyAddress: string + let moduleProxyFactoryAddress: string - let mockHatsAccountImplementation: MockHatsAccount; - let mockHatsAccountImplementationAddress: string; + let mockHatsAccountImplementation: MockHatsAccount + let mockHatsAccountImplementationAddress: string - let mockSablier: MockSablierV2LockupLinear; - let mockSablierAddress: string; + let mockSablier: MockSablierV2LockupLinear + let mockSablierAddress: string - let mockERC20: MockERC20; - let mockERC20Address: string; + let mockERC20: MockERC20 + let mockERC20Address: string beforeEach(async () => { - const signers = await hre.ethers.getSigners(); - const [deployer] = signers; - [, dao] = signers; - - mockHats = await new MockHats__factory(deployer).deploy(); - mockHatsAddress = await mockHats.getAddress(); - keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); - erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory( - deployer - ).deploy(); - mockHatsAccountImplementationAddress = - await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); - decentHatsAddress = await decentHats.getAddress(); - - const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); - const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = - await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + const signers = await hre.ethers.getSigners() + const [deployer] = signers + ;[, dao] = signers + + mockHats = await new MockHats__factory(deployer).deploy() + mockHatsAddress = await mockHats.getAddress() + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress() + decentHats = await new DecentHats_0_1_0__factory(deployer).deploy() + decentHatsAddress = await decentHats.getAddress() + + const moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() + moduleProxyFactoryAddress = await moduleProxyFactory.getAddress() + const adminHatMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy("TEST") + adminHatMasterCopyAddress = await adminHatMasterCopy.getAddress() + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory() + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton() + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress() + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + "setup", + [ [dao.address], 1, hre.ethers.ZeroAddress, @@ -126,207 +130,193 @@ describe("DecentHats_0_1_0", () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ]); + ] + ) - const saltNum = BigInt( - `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` - ); + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`) const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, gnosisSafeProxyFactory - ); - gnosisSafeAddress = predictedGnosisSafeAddress; + ) + gnosisSafeAddress = predictedGnosisSafeAddress await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, saltNum - ); + ) - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer) // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory( - deployer - ).deploy(); - mockSablierAddress = await mockSablier.getAddress(); + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy() + mockSablierAddress = await mockSablier.getAddress() - mockERC20 = await new MockERC20__factory(deployer).deploy( - "MockERC20", - "MCK" - ); - mockERC20Address = await mockERC20.getAddress(); + mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK") + mockERC20Address = await mockERC20.getAddress() - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); - }); + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")) + }) describe("DecentHats as a Module", () => { - let enableModuleTx: ethers.ContractTransactionResponse; + let enableModuleTx: ethers.ContractTransactionResponse beforeEach(async () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: - GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentHatsAddress] - ), + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( + "enableModule", + [decentHatsAddress] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); - }); + await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an EnabledModule event", async () => { - await expect(enableModuleTx) - .to.emit(gnosisSafe, "EnabledModule") - .withArgs(decentHatsAddress); - }); + await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentHatsAddress) + }) describe("Creating a new Top Hat and Tree", () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + let createAndDeclareTreeTx: ethers.ContractTransactionResponse beforeEach(async () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + moduleProxyFactory: moduleProxyFactoryAddress, + decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + eligibility: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, details: "", imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, + eligibility: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ] - ), + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + eligibility: ethers.ZeroAddress, + sablierParams: [], + }, + ], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an ExecutionFromModuleSuccess event", async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress); - }); + .withArgs(decentHatsAddress) + }) it("Emits some hatsTreeId ValueUpdated events", async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0"); - }); + .withArgs(gnosisSafeAddress, "topHatId", "0") + }) describe("Multiple calls", () => { - let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; + let createAndDeclareTreeTx2: ethers.ContractTransactionResponse beforeEach(async () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + moduleProxyFactory: moduleProxyFactoryAddress, + decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + eligibility: ethers.ZeroAddress, }, - ] - ), + hats: [], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx2).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); + await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an ExecutionFromModuleSuccess event", async () => { await expect(createAndDeclareTreeTx2) .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress); - }); + .withArgs(decentHatsAddress) + }) it("Creates Top Hats with sequential IDs", async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "4"); - }); - }); + .withArgs(gnosisSafeAddress, "topHatId", "4") + }) + }) describe("Creating Hats Accounts", () => { - let salt: string; + let salt: string beforeEach(async () => { salt = solidityPackedKeccak256( ["string", "uint256", "address"], ["DecentHats_0_1_0", await hre.getChainId(), decentHatsAddress] - ); - }); + ) + }) const getHatAccount = async (hatId: bigint) => { const hatAccountAddress = await erc6551Registry.account( @@ -335,283 +325,273 @@ describe("DecentHats_0_1_0", () => { await hre.getChainId(), mockHatsAddress, hatId - ); + ) const hatAccount = MockHatsAccount__factory.connect( hatAccountAddress, hre.ethers.provider - ); + ) - return hatAccount; - }; + return hatAccount + } it("Generates the correct Addresses for the current Hats", async () => { - const currentCount = await mockHats.count(); + const currentCount = await mockHats.count() for (let i = 0n; i < currentCount; i++) { - const topHatAccount = await getHatAccount(i); - expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq( - mockHatsAddress - ); + const topHatAccount = await getHatAccount(i) + expect(await topHatAccount.tokenId()).eq(i) + expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress) } - }); - }); - }); + }) + }) + }) describe("Creating a new Top Hat and Tree with Sablier Streams", () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; - let currentBlockTimestamp: number; + let createAndDeclareTreeTx: ethers.ContractTransactionResponse + let currentBlockTimestamp: number beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + moduleProxyFactory: moduleProxyFactoryAddress, + decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + eligibility: ethers.ZeroAddress, + }, + hats: [ + { maxSupply: 1, details: "", imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, + eligibility: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + eligibility: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ] - ), + ], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an ExecutionFromModuleSuccess event", async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress); - }); + .withArgs(decentHatsAddress) + }) it("Emits some hatsTreeId ValueUpdated events", async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0"); - }); + .withArgs(gnosisSafeAddress, "topHatId", "0") + }) it("Creates a Sablier stream for the hat with stream parameters", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(1); + ) + expect(streamCreatedEvents.length).to.equal(1) - const event = streamCreatedEvents[0]; - expect(event.args.sender).to.equal(gnosisSafeAddress); - expect(event.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event.args.totalAmount).to.equal(ethers.parseEther("100")); - }); + const event = streamCreatedEvents[0] + expect(event.args.sender).to.equal(gnosisSafeAddress) + expect(event.args.recipient).to.not.equal(ethers.ZeroAddress) + expect(event.args.totalAmount).to.equal(ethers.parseEther("100")) + }) it("Does not create a Sablier stream for hats without stream parameters", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created - }); + ) + expect(streamCreatedEvents.length).to.equal(1) // Only one stream should be created + }) it("Creates a Sablier stream with correct timestamps", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(1); + ) + expect(streamCreatedEvents.length).to.equal(1) - const streamId = streamCreatedEvents[0].args.streamId; - const stream = await mockSablier.getStream(streamId); + const streamId = streamCreatedEvents[0].args.streamId + const stream = await mockSablier.getStream(streamId) - expect(stream.startTime).to.equal(currentBlockTimestamp); - expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000); - }); - }); + expect(stream.startTime).to.equal(currentBlockTimestamp) + expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000) + }) + }) describe("Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat", () => { - let currentBlockTimestamp: number; + let currentBlockTimestamp: number beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + moduleProxyFactory: moduleProxyFactoryAddress, + decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + eligibility: ethers.ZeroAddress, + }, + hats: [ + { maxSupply: 1, details: "", imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + eligibility: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now }, - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("50"), - asset: mockERC20Address, - cancelable: false, - transferable: true, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, // No cliff - end: currentBlockTimestamp + 1296000, // 15 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("50"), + asset: mockERC20Address, + cancelable: false, + transferable: true, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, // No cliff + end: currentBlockTimestamp + 1296000, // 15 days from now }, - ], - }, - ], - }, - ] - ), + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + ], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Creates multiple Sablier streams for a single hat", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(2); + ) + expect(streamCreatedEvents.length).to.equal(2) - const event1 = streamCreatedEvents[0]; - expect(event1.args.sender).to.equal(gnosisSafeAddress); - expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")); + const event1 = streamCreatedEvents[0] + expect(event1.args.sender).to.equal(gnosisSafeAddress) + expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress) + expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")) - const event2 = streamCreatedEvents[1]; - expect(event2.args.sender).to.equal(gnosisSafeAddress); - expect(event2.args.recipient).to.equal(event1.args.recipient); - expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")); - }); + const event2 = streamCreatedEvents[1] + expect(event2.args.sender).to.equal(gnosisSafeAddress) + expect(event2.args.recipient).to.equal(event1.args.recipient) + expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")) + }) it("Creates streams with correct parameters", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); - expect(stream1.cancelable).to.be.true; - expect(stream1.transferable).to.be.false; - expect(stream1.endTime - stream1.startTime).to.equal(2592000); - - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); - expect(stream2.cancelable).to.be.false; - expect(stream2.transferable).to.be.true; - expect(stream2.endTime - stream2.startTime).to.equal(1296000); - }); + ) + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) + expect(stream1.cancelable).to.be.true + expect(stream1.transferable).to.be.false + expect(stream1.endTime - stream1.startTime).to.equal(2592000) + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) + expect(stream2.cancelable).to.be.false + expect(stream2.transferable).to.be.true + expect(stream2.endTime - stream2.startTime).to.equal(1296000) + }) it("Creates streams with correct timestamps", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); - expect(stream1.startTime).to.equal(currentBlockTimestamp); - expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); - - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); - expect(stream2.startTime).to.equal(currentBlockTimestamp); - expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); - }); - }); - }); -}); + ) + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) + expect(stream1.startTime).to.equal(currentBlockTimestamp) + expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000) + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) + expect(stream2.startTime).to.equal(currentBlockTimestamp) + expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000) + }) + }) + }) +}) From 62917d55fa20657bd89a4ec8212b67e69ae70861 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 02:17:08 -0400 Subject: [PATCH 019/206] update deploy with constructor arg --- ...utonomousAdminHat.ts => 018_deploy_DecentAutonomousAdmin.ts} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename deploy/core/{018_deploy_DecentAutonomousAdminHat.ts => 018_deploy_DecentAutonomousAdmin.ts} (80%) diff --git a/deploy/core/018_deploy_DecentAutonomousAdminHat.ts b/deploy/core/018_deploy_DecentAutonomousAdmin.ts similarity index 80% rename from deploy/core/018_deploy_DecentAutonomousAdminHat.ts rename to deploy/core/018_deploy_DecentAutonomousAdmin.ts index f1adb696..cbdb509d 100644 --- a/deploy/core/018_deploy_DecentAutonomousAdminHat.ts +++ b/deploy/core/018_deploy_DecentAutonomousAdmin.ts @@ -3,7 +3,7 @@ import { DeployFunction } from "hardhat-deploy/types"; import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentAutonomousAdmin"); + await deployNonUpgradeable(hre, "DecentAutonomousAdmin", ["0.1.0"]); }; export default func; From 3c067933cb5514e959a7764d2c14c4a93103c6b5 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 09:57:08 -0400 Subject: [PATCH 020/206] use existing salt --- contracts/DecentHats_0_1_0.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index b8ed2a75..ac7eed3d 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -235,9 +235,7 @@ contract DecentHats_0_1_0 { "setUp(uint256)", adminHatId ); - uint256 saltNonce = uint256( - keccak256(abi.encodePacked(block.timestamp, initializer)) - ); + uint256 saltNonce = uint256(salt); hatsProtocol.mintHat( hatId, moduleProxyFactory.deployModule( From bda7d794b6eb0f7754b217c9aa8d8c1f1171646b Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 09:57:35 -0400 Subject: [PATCH 021/206] remove only --- test/DecentHats_0_1_0.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index f1741567..6de8c37d 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -69,7 +69,7 @@ const executeSafeTransaction = async ({ return tx } -describe.only("DecentHats_0_1_0", () => { +describe("DecentHats_0_1_0", () => { let dao: SignerWithAddress let mockHats: MockHats From 6ff9499096cc310b8d15b000b59ad9dae886760f Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 27 Sep 2024 09:59:24 -0400 Subject: [PATCH 022/206] don't add new variables --- contracts/DecentHats_0_1_0.sol | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index ac7eed3d..6c568f43 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -231,17 +231,12 @@ contract DecentHats_0_1_0 { hatId ); - bytes memory initializer = abi.encodeWithSignature( - "setUp(uint256)", - adminHatId - ); - uint256 saltNonce = uint256(salt); hatsProtocol.mintHat( hatId, moduleProxyFactory.deployModule( decentAutonomousAdminMasterCopy, - initializer, - saltNonce + abi.encodeWithSignature("setUp(uint256)", adminHatId), + uint256(salt) ) ); } From ed62fee7c7ed23cf2cbfa93f0c46383f32e3bb53 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 27 Sep 2024 15:38:32 -0400 Subject: [PATCH 023/206] Beginnings of a DecentSablier module --- contracts/DecentSablier_0_1_0.sol | 42 +++++++ contracts/interfaces/sablier/ISablier.sol | 28 +++++ contracts/mocks/MockSablier.sol | 34 +++++ test/DecentSablier_0_1_0.test.ts | 143 ++++++++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 contracts/DecentSablier_0_1_0.sol create mode 100644 contracts/interfaces/sablier/ISablier.sol create mode 100644 contracts/mocks/MockSablier.sol create mode 100644 test/DecentSablier_0_1_0.test.ts diff --git a/contracts/DecentSablier_0_1_0.sol b/contracts/DecentSablier_0_1_0.sol new file mode 100644 index 00000000..1f8bd902 --- /dev/null +++ b/contracts/DecentSablier_0_1_0.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +pragma solidity =0.8.19; + +import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; +import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; +import {ISablier} from "./interfaces/sablier/ISablier.sol"; + +contract DecentSablier_0_1_0 { + string public constant NAME = "DecentSablier_0_1_0"; + + struct SablierStreamInfo { + uint256 streamId; + } + + function processSablierStreams( + address sablierContract, + SablierStreamInfo[] calldata streams + ) public { + ISablier sablier = ISablier(sablierContract); + + for (uint256 i = 0; i < streams.length; i++) { + uint256 streamId = streams[i].streamId; + + // Get the current balance available for withdrawal + uint256 availableBalance = sablier.balanceOf(streamId, msg.sender); + + if (availableBalance > 0) { + // Proxy the withdrawal call through the Safe + IAvatar(msg.sender).execTransactionFromModule( + sablierContract, + 0, + abi.encodeWithSelector( + ISablier.withdrawFromStream.selector, + streamId, + availableBalance + ), + Enum.Operation.Call + ); + } + } + } +} diff --git a/contracts/interfaces/sablier/ISablier.sol b/contracts/interfaces/sablier/ISablier.sol new file mode 100644 index 00000000..a11535ab --- /dev/null +++ b/contracts/interfaces/sablier/ISablier.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity =0.8.19; + +interface ISablier { + function getStream( + uint256 streamId + ) + external + view + returns ( + address sender, + address recipient, + uint256 deposit, + address tokenAddress, + uint256 startTime, + uint256 stopTime, + uint256 remainingBalance, + uint256 ratePerSecond + ); + function balanceOf( + uint256 streamId, + address who + ) external view returns (uint256 balance); + function withdrawFromStream( + uint256 streamId, + uint256 amount + ) external returns (bool); +} diff --git a/contracts/mocks/MockSablier.sol b/contracts/mocks/MockSablier.sol new file mode 100644 index 00000000..0d823195 --- /dev/null +++ b/contracts/mocks/MockSablier.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity =0.8.19; + +contract MockSablier { + mapping(uint256 => uint256) private streamBalances; + mapping(uint256 => uint256) private withdrawnAmounts; + + function setStreamBalance(uint256 streamId, uint256 balance) external { + streamBalances[streamId] = balance; + } + + function balanceOf( + uint256 streamId, + address + ) external view returns (uint256) { + return streamBalances[streamId]; + } + + function withdrawFromStream( + uint256 streamId, + uint256 amount + ) external returns (bool) { + require(streamBalances[streamId] >= amount, "Insufficient balance"); + streamBalances[streamId] -= amount; + withdrawnAmounts[streamId] += amount; + return true; + } + + function getWithdrawnAmount( + uint256 streamId + ) external view returns (uint256) { + return withdrawnAmounts[streamId]; + } +} diff --git a/test/DecentSablier_0_1_0.test.ts b/test/DecentSablier_0_1_0.test.ts new file mode 100644 index 00000000..05884254 --- /dev/null +++ b/test/DecentSablier_0_1_0.test.ts @@ -0,0 +1,143 @@ +import { + GnosisSafeL2, + GnosisSafeL2__factory, + DecentSablier_0_1_0__factory, + DecentSablier_0_1_0, +} from "../typechain-types"; + +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { expect } from "chai"; +import { ethers } from "ethers"; +import hre from "hardhat"; + +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, +} from "./GlobalSafeDeployments.test"; +import { + buildSafeTransaction, + buildSignatureBytes, + predictGnosisSafeAddress, + safeSignTypedData, +} from "./helpers"; + +import { MockSablier__factory } from "../typechain-types"; + +async function executeSafeTransaction({ + safe, + to, + value, + data, + operation, + signers, +}: { + safe: GnosisSafeL2; + to: string; + value?: bigint; + data?: string; + operation?: number; + signers: SignerWithAddress[]; +}) { + const safeTransactionData = { + to, + value: value || 0n, + data: data || "0x", + operation: operation || 0, + // Add the missing 'nonce' property + nonce: await safe.nonce(), + }; + const safeTransaction = await buildSafeTransaction(safeTransactionData); + const senderSignature = await safeSignTypedData( + signers[0], + safe, + safeTransaction + ); + const signatureBytes = buildSignatureBytes([senderSignature]); + // Change 'executeTransaction' to 'execTransaction' + return safe.execTransaction(safeTransaction, signatureBytes); +} + +describe("DecentSablier", () => { + let dao: SignerWithAddress; + let gnosisSafe: GnosisSafeL2; + let decentSablier: DecentSablier_0_1_0; + let decentSablierAddress: string; + let gnosisSafeAddress: string; + + let mockSablier: MockSablier; + + beforeEach(async () => { + // ... (setup code similar to DecentHats.test.ts) + // Deploy MockSablier + const MockSablier = await ethers.getContractFactory("MockSablier"); + mockSablier = await MockSablier.deploy(); + await mockSablier.deployed(); + }); + + describe("DecentSablier as a Module", () => { + let enableModuleTx: ethers.ContractTransactionResponse; + + beforeEach(async () => { + // ... (enable module code similar to DecentHats.test.ts) + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Emits an EnabledModule event", async () => { + await expect(enableModuleTx) + .to.emit(gnosisSafe, "EnabledModule") + .withArgs(decentSablierAddress); + }); + + describe("Processing Sablier Streams", () => { + let processSablierStreamsTx: ethers.ContractTransactionResponse; + + beforeEach(async () => { + // Set up mock stream balances + await mockSablier.setStreamBalance(1, ethers.utils.parseEther("100")); + await mockSablier.setStreamBalance(2, ethers.utils.parseEther("200")); + await mockSablier.setStreamBalance(3, ethers.utils.parseEther("300")); + + processSablierStreamsTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentSablierAddress, + data: DecentSablier_0_1_0__factory.createInterface().encodeFunctionData( + "processSablierStreams", + [ + mockSablier.address, + [{ streamId: 1 }, { streamId: 2 }, { streamId: 3 }], + ] + ), + signers: [dao], + }); + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(processSablierStreamsTx).to.emit( + gnosisSafe, + "ExecutionSuccess" + ); + }); + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(processSablierStreamsTx) + .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .withArgs(decentSablierAddress); + }); + + it("Withdraws from streams correctly", async () => { + expect(await mockSablier.getWithdrawnAmount(1)).to.equal( + ethers.utils.parseEther("100") + ); + expect(await mockSablier.getWithdrawnAmount(2)).to.equal( + ethers.utils.parseEther("200") + ); + expect(await mockSablier.getWithdrawnAmount(3)).to.equal( + ethers.utils.parseEther("300") + ); + }); + }); + }); +}); From ff7adfafc9bb4eda44c1cdd9ad1bcea81ab1194f Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 27 Sep 2024 15:39:31 -0400 Subject: [PATCH 024/206] Update contract and create some new Sablier interfaces --- contracts/DecentSablier_0_1_0.sol | 53 ++++++++----------- .../interfaces/sablier/ISablierV2Lockup.sol | 12 +++++ .../sablier/ISablierV2LockupLinear.sol | 3 +- 3 files changed, 36 insertions(+), 32 deletions(-) create mode 100644 contracts/interfaces/sablier/ISablierV2Lockup.sol diff --git a/contracts/DecentSablier_0_1_0.sol b/contracts/DecentSablier_0_1_0.sol index 1f8bd902..5662ac63 100644 --- a/contracts/DecentSablier_0_1_0.sol +++ b/contracts/DecentSablier_0_1_0.sol @@ -3,40 +3,31 @@ pragma solidity =0.8.19; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {ISablier} from "./interfaces/sablier/ISablier.sol"; +import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; -contract DecentSablier_0_1_0 { - string public constant NAME = "DecentSablier_0_1_0"; +contract DecentSablierStreamManagement { + string public constant NAME = "DecentSablierStreamManagement"; - struct SablierStreamInfo { - uint256 streamId; - } - - function processSablierStreams( - address sablierContract, - SablierStreamInfo[] calldata streams + function withdrawMaxFromStream( + ISablierV2LockupLinear sablier, + uint256 streamId ) public { - ISablier sablier = ISablier(sablierContract); - - for (uint256 i = 0; i < streams.length; i++) { - uint256 streamId = streams[i].streamId; - - // Get the current balance available for withdrawal - uint256 availableBalance = sablier.balanceOf(streamId, msg.sender); - - if (availableBalance > 0) { - // Proxy the withdrawal call through the Safe - IAvatar(msg.sender).execTransactionFromModule( - sablierContract, - 0, - abi.encodeWithSelector( - ISablier.withdrawFromStream.selector, - streamId, - availableBalance - ), - Enum.Operation.Call - ); - } + // Check if there are funds to withdraw + uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId); + if (withdrawableAmount == 0) { + return; } + + // Proxy the Sablier withdrawMax call through IAvatar (Safe) + IAvatar(msg.sender).execTransactionFromModule( + address(sablier), + 0, + abi.encodeWithSignature( + "withdrawMax(uint256,address)", + streamId, + msg.sender + ), + Enum.Operation.Call + ); } } diff --git a/contracts/interfaces/sablier/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol new file mode 100644 index 00000000..a6ee2545 --- /dev/null +++ b/contracts/interfaces/sablier/ISablierV2Lockup.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface ISablierV2Lockup { + function getRecipient( + uint256 streamId + ) external view returns (address recipient); + + function withdrawableAmountOf( + uint256 streamId + ) external view returns (uint128 withdrawableAmount); +} diff --git a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol index 0aa6cac9..ebcc6d50 100644 --- a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol +++ b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol @@ -2,9 +2,10 @@ pragma solidity ^0.8.0; import {LockupLinear} from "./LockupLinear.sol"; +import {ISablierV2Lockup} from "./ISablierV2Lockup.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -interface ISablierV2LockupLinear { +interface ISablierV2LockupLinear is ISablierV2Lockup { function createWithTimestamps( LockupLinear.CreateWithTimestamps calldata params ) external returns (uint256 streamId); From e0df21ee1403be77aa84de19e389c63b6fa1a462 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 27 Sep 2024 15:42:36 -0400 Subject: [PATCH 025/206] Remove unused interface, finish mock implementation --- contracts/interfaces/sablier/ISablier.sol | 28 ------------------- contracts/mocks/MockSablierV2LockupLinear.sol | 4 +++ 2 files changed, 4 insertions(+), 28 deletions(-) delete mode 100644 contracts/interfaces/sablier/ISablier.sol diff --git a/contracts/interfaces/sablier/ISablier.sol b/contracts/interfaces/sablier/ISablier.sol deleted file mode 100644 index a11535ab..00000000 --- a/contracts/interfaces/sablier/ISablier.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -interface ISablier { - function getStream( - uint256 streamId - ) - external - view - returns ( - address sender, - address recipient, - uint256 deposit, - address tokenAddress, - uint256 startTime, - uint256 stopTime, - uint256 remainingBalance, - uint256 ratePerSecond - ); - function balanceOf( - uint256 streamId, - address who - ) external view returns (uint256 balance); - function withdrawFromStream( - uint256 streamId, - uint256 amount - ) external returns (bool); -} diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 7d737bb4..f0ad0030 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -156,4 +156,8 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { stream.recipient = recipient; } + + function getRecipient(uint256 streamId) external view returns (address) { + return streams[streamId].recipient; + } } From fa0369142f20a0989814e5a8ddd4eac550d4ed5d Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 27 Sep 2024 15:44:31 -0400 Subject: [PATCH 026/206] Comment out new tests, for now --- test/DecentSablier_0_1_0.test.ts | 286 +++++++++++++++---------------- 1 file changed, 143 insertions(+), 143 deletions(-) diff --git a/test/DecentSablier_0_1_0.test.ts b/test/DecentSablier_0_1_0.test.ts index 05884254..935f46f5 100644 --- a/test/DecentSablier_0_1_0.test.ts +++ b/test/DecentSablier_0_1_0.test.ts @@ -1,143 +1,143 @@ -import { - GnosisSafeL2, - GnosisSafeL2__factory, - DecentSablier_0_1_0__factory, - DecentSablier_0_1_0, -} from "../typechain-types"; - -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; - -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, -} from "./GlobalSafeDeployments.test"; -import { - buildSafeTransaction, - buildSignatureBytes, - predictGnosisSafeAddress, - safeSignTypedData, -} from "./helpers"; - -import { MockSablier__factory } from "../typechain-types"; - -async function executeSafeTransaction({ - safe, - to, - value, - data, - operation, - signers, -}: { - safe: GnosisSafeL2; - to: string; - value?: bigint; - data?: string; - operation?: number; - signers: SignerWithAddress[]; -}) { - const safeTransactionData = { - to, - value: value || 0n, - data: data || "0x", - operation: operation || 0, - // Add the missing 'nonce' property - nonce: await safe.nonce(), - }; - const safeTransaction = await buildSafeTransaction(safeTransactionData); - const senderSignature = await safeSignTypedData( - signers[0], - safe, - safeTransaction - ); - const signatureBytes = buildSignatureBytes([senderSignature]); - // Change 'executeTransaction' to 'execTransaction' - return safe.execTransaction(safeTransaction, signatureBytes); -} - -describe("DecentSablier", () => { - let dao: SignerWithAddress; - let gnosisSafe: GnosisSafeL2; - let decentSablier: DecentSablier_0_1_0; - let decentSablierAddress: string; - let gnosisSafeAddress: string; - - let mockSablier: MockSablier; - - beforeEach(async () => { - // ... (setup code similar to DecentHats.test.ts) - // Deploy MockSablier - const MockSablier = await ethers.getContractFactory("MockSablier"); - mockSablier = await MockSablier.deploy(); - await mockSablier.deployed(); - }); - - describe("DecentSablier as a Module", () => { - let enableModuleTx: ethers.ContractTransactionResponse; - - beforeEach(async () => { - // ... (enable module code similar to DecentHats.test.ts) - }); - - it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); - }); - - it("Emits an EnabledModule event", async () => { - await expect(enableModuleTx) - .to.emit(gnosisSafe, "EnabledModule") - .withArgs(decentSablierAddress); - }); - - describe("Processing Sablier Streams", () => { - let processSablierStreamsTx: ethers.ContractTransactionResponse; - - beforeEach(async () => { - // Set up mock stream balances - await mockSablier.setStreamBalance(1, ethers.utils.parseEther("100")); - await mockSablier.setStreamBalance(2, ethers.utils.parseEther("200")); - await mockSablier.setStreamBalance(3, ethers.utils.parseEther("300")); - - processSablierStreamsTx = await executeSafeTransaction({ - safe: gnosisSafe, - to: decentSablierAddress, - data: DecentSablier_0_1_0__factory.createInterface().encodeFunctionData( - "processSablierStreams", - [ - mockSablier.address, - [{ streamId: 1 }, { streamId: 2 }, { streamId: 3 }], - ] - ), - signers: [dao], - }); - }); - - it("Emits an ExecutionSuccess event", async () => { - await expect(processSablierStreamsTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); - - it("Emits an ExecutionFromModuleSuccess event", async () => { - await expect(processSablierStreamsTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentSablierAddress); - }); - - it("Withdraws from streams correctly", async () => { - expect(await mockSablier.getWithdrawnAmount(1)).to.equal( - ethers.utils.parseEther("100") - ); - expect(await mockSablier.getWithdrawnAmount(2)).to.equal( - ethers.utils.parseEther("200") - ); - expect(await mockSablier.getWithdrawnAmount(3)).to.equal( - ethers.utils.parseEther("300") - ); - }); - }); - }); -}); +// import { +// GnosisSafeL2, +// GnosisSafeL2__factory, +// DecentSablier_0_1_0__factory, +// DecentSablier_0_1_0, +// } from "../typechain-types"; + +// import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +// import { expect } from "chai"; +// import { ethers } from "ethers"; +// import hre from "hardhat"; + +// import { +// getGnosisSafeL2Singleton, +// getGnosisSafeProxyFactory, +// } from "./GlobalSafeDeployments.test"; +// import { +// buildSafeTransaction, +// buildSignatureBytes, +// predictGnosisSafeAddress, +// safeSignTypedData, +// } from "./helpers"; + +// import { MockSablier__factory } from "../typechain-types"; + +// async function executeSafeTransaction({ +// safe, +// to, +// value, +// data, +// operation, +// signers, +// }: { +// safe: GnosisSafeL2; +// to: string; +// value?: bigint; +// data?: string; +// operation?: number; +// signers: SignerWithAddress[]; +// }) { +// const safeTransactionData = { +// to, +// value: value || 0n, +// data: data || "0x", +// operation: operation || 0, +// // Add the missing 'nonce' property +// nonce: await safe.nonce(), +// }; +// const safeTransaction = await buildSafeTransaction(safeTransactionData); +// const senderSignature = await safeSignTypedData( +// signers[0], +// safe, +// safeTransaction +// ); +// const signatureBytes = buildSignatureBytes([senderSignature]); +// // Change 'executeTransaction' to 'execTransaction' +// return safe.execTransaction(safeTransaction, signatureBytes); +// } + +// describe("DecentSablier", () => { +// let dao: SignerWithAddress; +// let gnosisSafe: GnosisSafeL2; +// let decentSablier: DecentSablier_0_1_0; +// let decentSablierAddress: string; +// let gnosisSafeAddress: string; + +// let mockSablier: MockSablier; + +// beforeEach(async () => { +// // ... (setup code similar to DecentHats.test.ts) +// // Deploy MockSablier +// const MockSablier = await ethers.getContractFactory("MockSablier"); +// mockSablier = await MockSablier.deploy(); +// await mockSablier.deployed(); +// }); + +// describe("DecentSablier as a Module", () => { +// let enableModuleTx: ethers.ContractTransactionResponse; + +// beforeEach(async () => { +// // ... (enable module code similar to DecentHats.test.ts) +// }); + +// it("Emits an ExecutionSuccess event", async () => { +// await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); +// }); + +// it("Emits an EnabledModule event", async () => { +// await expect(enableModuleTx) +// .to.emit(gnosisSafe, "EnabledModule") +// .withArgs(decentSablierAddress); +// }); + +// describe("Processing Sablier Streams", () => { +// let processSablierStreamsTx: ethers.ContractTransactionResponse; + +// beforeEach(async () => { +// // Set up mock stream balances +// await mockSablier.setStreamBalance(1, ethers.utils.parseEther("100")); +// await mockSablier.setStreamBalance(2, ethers.utils.parseEther("200")); +// await mockSablier.setStreamBalance(3, ethers.utils.parseEther("300")); + +// processSablierStreamsTx = await executeSafeTransaction({ +// safe: gnosisSafe, +// to: decentSablierAddress, +// data: DecentSablier_0_1_0__factory.createInterface().encodeFunctionData( +// "processSablierStreams", +// [ +// mockSablier.address, +// [{ streamId: 1 }, { streamId: 2 }, { streamId: 3 }], +// ] +// ), +// signers: [dao], +// }); +// }); + +// it("Emits an ExecutionSuccess event", async () => { +// await expect(processSablierStreamsTx).to.emit( +// gnosisSafe, +// "ExecutionSuccess" +// ); +// }); + +// it("Emits an ExecutionFromModuleSuccess event", async () => { +// await expect(processSablierStreamsTx) +// .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") +// .withArgs(decentSablierAddress); +// }); + +// it("Withdraws from streams correctly", async () => { +// expect(await mockSablier.getWithdrawnAmount(1)).to.equal( +// ethers.utils.parseEther("100") +// ); +// expect(await mockSablier.getWithdrawnAmount(2)).to.equal( +// ethers.utils.parseEther("200") +// ); +// expect(await mockSablier.getWithdrawnAmount(3)).to.equal( +// ethers.utils.parseEther("300") +// ); +// }); +// }); +// }); +// }); From ce2087c2c6e46560d04bfd133a9fb33f0b6bd8db Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:47:09 -0400 Subject: [PATCH 027/206] add interface for HatModuleFactory --- contracts/interfaces/IHatModuleFactory.sol | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 contracts/interfaces/IHatModuleFactory.sol diff --git a/contracts/interfaces/IHatModuleFactory.sol b/contracts/interfaces/IHatModuleFactory.sol new file mode 100644 index 00000000..46c74ac0 --- /dev/null +++ b/contracts/interfaces/IHatModuleFactory.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + + +interface IHatsModuleFactory { + function createHatsModule( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + bytes calldata _initData, + uint256 _saltNonce + ) external returns (address _instance); + + function getHatsModuleAddress( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + uint256 _saltNonce + ) external view returns (address); +} From 04c2639fa8aff480b3ac5cbc33aebdf4749d49d9 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 1 Oct 2024 02:20:22 -0400 Subject: [PATCH 028/206] update to add electionModuleAddress to termed roles --- contracts/DecentHats_0_1_0.sol | 66 +++++++++++++++++++++++++++-- contracts/interfaces/hats/IHats.sol | 2 + contracts/mocks/MockHats.sol | 2 + contracts/mocks/MockHatsAdmin.sol | 4 ++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index 6c568f43..8e6bfcde 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -11,6 +11,8 @@ import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinea import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; +import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; +import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; contract DecentHats_0_1_0 { string public constant NAME = "DecentHats_0_1_0"; @@ -26,14 +28,20 @@ contract DecentHats_0_1_0 { LockupLinear.Broker broker; } + struct TermedParams { + uint128 firstTermEnd; + address[] nominatedWearers; + } + struct Hat { uint32 maxSupply; string details; string imageURI; - address eligibility; bool isMutable; address wearer; + bool isTermed; SablierStreamParams[] sablierParams; // Optional Sablier stream parameters + TermedParams termedParams; // Optional termed parameters } struct CreateTreeParams { @@ -47,6 +55,8 @@ contract DecentHats_0_1_0 { string topHatImageURI; Hat adminHat; Hat[] hats; + IHatsModuleFactory hatsModuleFactory; + address hatsElectionEligibilityImplementation; } function getSalt() internal view returns (bytes32 salt) { @@ -96,8 +106,9 @@ contract DecentHats_0_1_0 { adminHatId, _hat.details, _hat.maxSupply, + // ? @todo should be this be dead HATS address? + topHatAccount, topHatAccount, - _hat.eligibility, _hat.isMutable, _hat.imageURI ); @@ -150,10 +161,27 @@ contract DecentHats_0_1_0 { address topHatAccount, IERC6551Registry registry, address hatsAccountImplementation, - bytes32 salt + bytes32 salt, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionEligibilityImplementation, + uint256 topHatId ) internal returns (uint256 hatId, address accountAddress) { hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); + if (hat.isTermed) { + // Create election module and set as eligiblity, elect, and start next term + createElectionModuleAndExecuteFirstTerm( + hatsProtocol, + hatsModuleFactory, + hatsElectionEligibilityImplementation, + hatId, + hat.termedParams.firstTermEnd, + hat.termedParams.nominatedWearers, + abi.encodePacked(topHatId), + uint256(salt) + ); + } + accountAddress = createAccount( registry, hatsAccountImplementation, @@ -241,6 +269,33 @@ contract DecentHats_0_1_0 { ); } + function createElectionModuleAndExecuteFirstTerm( + IHats hatsProtocol, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionEligibilityImplementation, + uint256 hatId, + uint128 firstTermEnd, + address[] memory nominatedWearer, + bytes memory otherImmutableArgs, + uint256 saltNonce + ) internal returns (address) { + address electionModuleAddress = hatsModuleFactory.createHatsModule( + hatsElectionEligibilityImplementation, + hatId, + otherImmutableArgs, + abi.encode(firstTermEnd), + saltNonce + ); + hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); + + IHatsElectionEligibility(electionModuleAddress).elect( + firstTermEnd, + nominatedWearer + ); + IHatsElectionEligibility(electionModuleAddress).startNextTerm(); + return electionModuleAddress; + } + function createAndDeclareTree(CreateTreeParams calldata params) public { bytes32 salt = getSalt(); @@ -275,7 +330,10 @@ contract DecentHats_0_1_0 { topHatAccount, params.registry, params.hatsAccountImplementation, - salt + salt, + params.hatsModuleFactory, + params.hatsElectionEligibilityImplementation, + topHatId ); unchecked { diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index 3a3743ea..0f4218b7 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -48,4 +48,6 @@ interface IHats { address _user, uint256 _hatId ) external view returns (bool isWearer); + + function changeHatEligibility(uint256 _hatId, address _newEligibility) external; } diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index 1cf74405..17859685 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -42,4 +42,6 @@ contract MockHats is IHats { address _user, uint256 _hatId ) external view returns (bool isWearer) {} + + function changeHatEligibility(uint256, address) external {} } diff --git a/contracts/mocks/MockHatsAdmin.sol b/contracts/mocks/MockHatsAdmin.sol index 5b7fef2c..914c0d30 100644 --- a/contracts/mocks/MockHatsAdmin.sol +++ b/contracts/mocks/MockHatsAdmin.sol @@ -74,4 +74,8 @@ contract MockHatsAutoAdmin is IHats { from; wearer[_hatId] = to; } + + function changeHatEligibility(uint256 _hatId, address _newEligibility) external override { + eligibility[_hatId] = _newEligibility; + } } From f379a19ee8d3d5a2cdedef8ddd7abb689cb65881 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 1 Oct 2024 10:02:50 -0400 Subject: [PATCH 029/206] update test with new params --- contracts/mocks/MockHatsModuleFactory.sol | 36 ++++++++++++ test/DecentHats_0_1_0.test.ts | 72 ++++++++++++++++++++--- 2 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 contracts/mocks/MockHatsModuleFactory.sol diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol new file mode 100644 index 00000000..2bfb92ba --- /dev/null +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import {IHatsModuleFactory} from "../interfaces/IHatModuleFactory.sol"; + +contract MockHatsModuleFactory is IHatsModuleFactory { + function createHatsModule( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + bytes calldata _initData, + uint256 _saltNonce + ) external pure returns (address _instance) { + // Silence unused variable warnings + _implementation; + _hatId; + _otherImmutableArgs; + _initData; + _saltNonce; + return address(0); + } + + function getHatsModuleAddress( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + uint256 _saltNonce + ) external pure returns (address) { + // Silence unused variable warnings + _implementation; + _hatId; + _otherImmutableArgs; + _saltNonce; + return address(0); + } +} diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 6de8c37d..b99292cb 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -17,6 +17,7 @@ import { MockERC20, DecentAutonomousAdmin__factory, ModuleProxyFactory__factory, + MockHatsElectionEligibility__factory, } from "../typechain-types" import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" @@ -96,6 +97,9 @@ describe("DecentHats_0_1_0", () => { let mockERC20: MockERC20 let mockERC20Address: string + let mockHatsElectionEligibilityImplementationAddress: string + let mockHatsModuleFactoryAddress: string + beforeEach(async () => { const signers = await hre.ethers.getSigners() const [deployer] = signers @@ -103,6 +107,12 @@ describe("DecentHats_0_1_0", () => { mockHats = await new MockHats__factory(deployer).deploy() mockHatsAddress = await mockHats.getAddress() + const mockHatsElectionEligibilityImplementation = + await new MockHatsElectionEligibility__factory(deployer).deploy() + mockHatsElectionEligibilityImplementationAddress = + await mockHatsElectionEligibilityImplementation.getAddress() + const mockHatsModuleFactory = await new ModuleProxyFactory__factory(deployer).deploy() + mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress() keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() @@ -209,8 +219,12 @@ describe("DecentHats_0_1_0", () => { imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - eligibility: ethers.ZeroAddress, sablierParams: [], + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -219,8 +233,12 @@ describe("DecentHats_0_1_0", () => { imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - eligibility: ethers.ZeroAddress, sablierParams: [], + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, { maxSupply: 1, @@ -228,10 +246,16 @@ describe("DecentHats_0_1_0", () => { imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - eligibility: ethers.ZeroAddress, sablierParams: [], + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -281,9 +305,15 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - eligibility: ethers.ZeroAddress, + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, hats: [], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -376,7 +406,11 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - eligibility: ethers.ZeroAddress, + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -385,7 +419,6 @@ describe("DecentHats_0_1_0", () => { imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - eligibility: ethers.ZeroAddress, sablierParams: [ { sablier: mockSablierAddress, @@ -402,6 +435,11 @@ describe("DecentHats_0_1_0", () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, { maxSupply: 1, @@ -409,10 +447,16 @@ describe("DecentHats_0_1_0", () => { imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - eligibility: ethers.ZeroAddress, sablierParams: [], + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -497,7 +541,11 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - eligibility: ethers.ZeroAddress, + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -506,7 +554,6 @@ describe("DecentHats_0_1_0", () => { imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - eligibility: ethers.ZeroAddress, sablierParams: [ { sablier: mockSablierAddress, @@ -537,8 +584,15 @@ describe("DecentHats_0_1_0", () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], + isTermed: false, + termedParams: { + firstTermEnd: 0, + nominatedWearers: [], + }, }, ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, ] ), From 79fd8db0c36f01ad73806d8fddbd28f3bce1907c Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:25:32 -0400 Subject: [PATCH 030/206] rename param --- contracts/DecentHats_0_1_0.sol | 10 +++++----- test/DecentHats_0_1_0.test.ts | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index 8e6bfcde..06ce94fe 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -29,7 +29,7 @@ contract DecentHats_0_1_0 { } struct TermedParams { - uint128 firstTermEnd; + uint128 termEndTs; address[] nominatedWearers; } @@ -175,7 +175,7 @@ contract DecentHats_0_1_0 { hatsModuleFactory, hatsElectionEligibilityImplementation, hatId, - hat.termedParams.firstTermEnd, + hat.termedParams.termEndTs, hat.termedParams.nominatedWearers, abi.encodePacked(topHatId), uint256(salt) @@ -274,7 +274,7 @@ contract DecentHats_0_1_0 { IHatsModuleFactory hatsModuleFactory, address hatsElectionEligibilityImplementation, uint256 hatId, - uint128 firstTermEnd, + uint128 termEndTs, address[] memory nominatedWearer, bytes memory otherImmutableArgs, uint256 saltNonce @@ -283,13 +283,13 @@ contract DecentHats_0_1_0 { hatsElectionEligibilityImplementation, hatId, otherImmutableArgs, - abi.encode(firstTermEnd), + abi.encode(termEndTs), saltNonce ); hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); IHatsElectionEligibility(electionModuleAddress).elect( - firstTermEnd, + termEndTs, nominatedWearer ); IHatsElectionEligibility(electionModuleAddress).startNextTerm(); diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index b99292cb..5023075c 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -222,7 +222,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -236,7 +236,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -249,7 +249,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -307,7 +307,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -408,7 +408,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -437,7 +437,7 @@ describe("DecentHats_0_1_0", () => { ], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -450,7 +450,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -543,7 +543,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, @@ -586,7 +586,7 @@ describe("DecentHats_0_1_0", () => { ], isTermed: false, termedParams: { - firstTermEnd: 0, + termEndTs: 0, nominatedWearers: [], }, }, From 7fe694788b878da0c37b3d82b677fe79eb61672a Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 3 Oct 2024 21:55:47 -0400 Subject: [PATCH 031/206] revert use of moduleProxyfactory to deploy DecentAutoAdmin --- contracts/DecentAutonomousAdmin.sol | 8 +------- contracts/DecentHats_0_1_0.sol | 17 +++-------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index d6aef8be..f228f346 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -24,14 +24,8 @@ contract DecentAutonomousAdmin { // ////////////////////////////////////////////////////////////// // Constructor // ////////////////////////////////////////////////////////////// - constructor(string memory _version) { + constructor(string memory _version, uint256 _adminHatId) { version_ = _version; - } - - // ////////////////////////////////////////////////////////////// - // Initializer - // ////////////////////////////////////////////////////////////// - function setUp(uint256 _adminHatId) public { adminHatId = _adminHatId; } diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index 06ce94fe..be3684ad 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -10,7 +10,6 @@ import {IHats} from "./interfaces/hats/IHats.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; -import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; @@ -47,8 +46,6 @@ contract DecentHats_0_1_0 { struct CreateTreeParams { IHats hatsProtocol; address hatsAccountImplementation; - ModuleProxyFactory moduleProxyFactory; - address decentAutonomousAdminMasterCopy; IERC6551Registry registry; address keyValuePairs; string topHatDetails; @@ -245,9 +242,7 @@ contract DecentHats_0_1_0 { address topHatAccount, IERC6551Registry registry, address hatsAccountImplementation, - bytes32 salt, - ModuleProxyFactory moduleProxyFactory, - address decentAutonomousAdminMasterCopy + bytes32 salt ) internal returns (uint256 hatId, address accountAddress) { hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); @@ -261,11 +256,7 @@ contract DecentHats_0_1_0 { hatsProtocol.mintHat( hatId, - moduleProxyFactory.deployModule( - decentAutonomousAdminMasterCopy, - abi.encodeWithSignature("setUp(uint256)", adminHatId), - uint256(salt) - ) + address(new DecentAutonomousAdmin("0_0_1", adminHatId)) ); } @@ -317,9 +308,7 @@ contract DecentHats_0_1_0 { topHatAccount, params.registry, params.hatsAccountImplementation, - salt, - params.moduleProxyFactory, - params.decentAutonomousAdminMasterCopy + salt ); for (uint256 i = 0; i < params.hats.length; ) { From 5cdba24670ba02978ab6c70382bcbfe3de98b1ae Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 3 Oct 2024 23:50:16 -0400 Subject: [PATCH 032/206] rename termEndTs -> termEndDateTs --- contracts/DecentHats_0_1_0.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index be3684ad..ced33ddc 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -28,7 +28,7 @@ contract DecentHats_0_1_0 { } struct TermedParams { - uint128 termEndTs; + uint128 termEndDateTs; address[] nominatedWearers; } @@ -172,7 +172,7 @@ contract DecentHats_0_1_0 { hatsModuleFactory, hatsElectionEligibilityImplementation, hatId, - hat.termedParams.termEndTs, + hat.termedParams.termEndDateTs, hat.termedParams.nominatedWearers, abi.encodePacked(topHatId), uint256(salt) @@ -265,7 +265,7 @@ contract DecentHats_0_1_0 { IHatsModuleFactory hatsModuleFactory, address hatsElectionEligibilityImplementation, uint256 hatId, - uint128 termEndTs, + uint128 termEndDateTs, address[] memory nominatedWearer, bytes memory otherImmutableArgs, uint256 saltNonce @@ -274,13 +274,13 @@ contract DecentHats_0_1_0 { hatsElectionEligibilityImplementation, hatId, otherImmutableArgs, - abi.encode(termEndTs), + abi.encode(termEndDateTs), saltNonce ); hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); IHatsElectionEligibility(electionModuleAddress).elect( - termEndTs, + termEndDateTs, nominatedWearer ); IHatsElectionEligibility(electionModuleAddress).startNextTerm(); From 69641f5f860f754000cb536a5ebffc4a8f9fba0f Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 3 Oct 2024 23:50:21 -0400 Subject: [PATCH 033/206] Update tests to support changes --- test/DecentAutonomousAdmin.test.ts | 20 +++--------- test/DecentHats_0_1_0.test.ts | 51 +++++++++++------------------- 2 files changed, 24 insertions(+), 47 deletions(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index 68fc2ec3..7dcadc64 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -31,8 +31,7 @@ describe("DecentAutonomousAdminHat", function () { beforeEach(async function () { // Get signers - ;[deployer, currentWearer, nominatedWearer, randomUser] = - await hre.ethers.getSigners() + ;[deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners() moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() // Deploy MockHatsAutoAdmin (Mock Hats Protocol) @@ -55,23 +54,14 @@ describe("DecentAutonomousAdminHat", function () { const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0] // Deploy DecentAutonomousAdminHat contract with the admin hat ID - adminHatMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy("TEST") - const proxyDeployTx = await moduleProxyFactory.deployModule( - await adminHatMasterCopy.getAddress(), - adminHatMasterCopy.interface.encodeFunctionData("setUp", [adminHatId]), - 1n - ) - const proxyDeployTxReceipt = await proxyDeployTx.wait() - const proxyAddress = await proxyDeployTxReceipt?.toJSON().logs[0].args[0] - - adminHat = DecentAutonomousAdmin__factory.connect(proxyAddress, deployer) - + adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy("TEST", adminHatId) + const adminHatAddress = await adminHat.getAddress() // Mint the admin hat to adminHatWearer - await hatsProtocol.mintHat(adminHatId, proxyAddress) + await hatsProtocol.mintHat(adminHatId, adminHatAddress) // Create User Hat under the admin hat const createUserTx = await hatsProtocol.createHat( - proxyAddress, // Admin address (adminHat contract) + adminHatAddress, // Admin address (adminHat contract) "Details", // Hat details 100, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 5023075c..e93af2f8 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -15,8 +15,7 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, - DecentAutonomousAdmin__factory, - ModuleProxyFactory__factory, + MockHatsModuleFactory__factory, MockHatsElectionEligibility__factory, } from "../typechain-types" @@ -85,9 +84,6 @@ describe("DecentHats_0_1_0", () => { let gnosisSafeAddress: string let erc6551Registry: ERC6551Registry - let adminHatMasterCopyAddress: string - let moduleProxyFactoryAddress: string - let mockHatsAccountImplementation: MockHatsAccount let mockHatsAccountImplementationAddress: string @@ -111,7 +107,7 @@ describe("DecentHats_0_1_0", () => { await new MockHatsElectionEligibility__factory(deployer).deploy() mockHatsElectionEligibilityImplementationAddress = await mockHatsElectionEligibilityImplementation.getAddress() - const mockHatsModuleFactory = await new ModuleProxyFactory__factory(deployer).deploy() + const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy() mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress() keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() @@ -120,11 +116,6 @@ describe("DecentHats_0_1_0", () => { decentHats = await new DecentHats_0_1_0__factory(deployer).deploy() decentHatsAddress = await decentHats.getAddress() - const moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() - moduleProxyFactoryAddress = await moduleProxyFactory.getAddress() - const adminHatMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy("TEST") - adminHatMasterCopyAddress = await adminHatMasterCopy.getAddress() - const gnosisSafeProxyFactory = getGnosisSafeProxyFactory() const gnosisSafeL2Singleton = getGnosisSafeL2Singleton() const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress() @@ -209,8 +200,6 @@ describe("DecentHats_0_1_0", () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - moduleProxyFactory: moduleProxyFactoryAddress, - decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, topHatDetails: "", topHatImageURI: "", adminHat: { @@ -222,7 +211,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, @@ -236,7 +225,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, @@ -249,13 +238,14 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -294,8 +284,6 @@ describe("DecentHats_0_1_0", () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - moduleProxyFactory: moduleProxyFactoryAddress, - decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, topHatDetails: "", topHatImageURI: "", adminHat: { @@ -307,13 +295,14 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, hats: [], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -395,8 +384,6 @@ describe("DecentHats_0_1_0", () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - moduleProxyFactory: moduleProxyFactoryAddress, - decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, topHatDetails: "", topHatImageURI: "", adminHat: { @@ -408,7 +395,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, @@ -437,7 +424,7 @@ describe("DecentHats_0_1_0", () => { ], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, @@ -450,13 +437,14 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -530,8 +518,6 @@ describe("DecentHats_0_1_0", () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - moduleProxyFactory: moduleProxyFactoryAddress, - decentAutonomousAdminMasterCopy: adminHatMasterCopyAddress, topHatDetails: "", topHatImageURI: "", adminHat: { @@ -543,7 +529,7 @@ describe("DecentHats_0_1_0", () => { sablierParams: [], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, @@ -586,13 +572,14 @@ describe("DecentHats_0_1_0", () => { ], isTermed: false, termedParams: { - termEndTs: 0, + termEndDateTs: 0, nominatedWearers: [], }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, }, ] ), From 0f747ac11773ec365a909f13b02b684163c1afb8 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Fri, 4 Oct 2024 13:12:02 +0100 Subject: [PATCH 034/206] Update withdrawMaxFromStream --- contracts/DecentSablier_0_1_0.sol | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/contracts/DecentSablier_0_1_0.sol b/contracts/DecentSablier_0_1_0.sol index 5662ac63..2fe0e115 100644 --- a/contracts/DecentSablier_0_1_0.sol +++ b/contracts/DecentSablier_0_1_0.sol @@ -10,7 +10,9 @@ contract DecentSablierStreamManagement { function withdrawMaxFromStream( ISablierV2LockupLinear sablier, - uint256 streamId + HatsAccount1ofNAbi smartAccount, + uint256 streamId, + address to, ) public { // Check if there are funds to withdraw uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId); @@ -20,12 +22,18 @@ contract DecentSablierStreamManagement { // Proxy the Sablier withdrawMax call through IAvatar (Safe) IAvatar(msg.sender).execTransactionFromModule( - address(sablier), + address(smartAccount), 0, abi.encodeWithSignature( - "withdrawMax(uint256,address)", - streamId, - msg.sender + "execute(address,uint256,bytes,uint8)", + address(sablier), + 0, + abi.encodeWithSignature( + "withdrawMax(uint256,address)", + streamId, + to + ), + 0 ), Enum.Operation.Call ); From 67601b11914382e5c5edc2a44b6dbecfb14c8260 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Fri, 4 Oct 2024 16:56:38 +0100 Subject: [PATCH 035/206] Add `cancelStream` --- contracts/DecentSablier_0_1_0.sol | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/contracts/DecentSablier_0_1_0.sol b/contracts/DecentSablier_0_1_0.sol index 2fe0e115..8bcbeefd 100644 --- a/contracts/DecentSablier_0_1_0.sol +++ b/contracts/DecentSablier_0_1_0.sol @@ -38,4 +38,21 @@ contract DecentSablierStreamManagement { Enum.Operation.Call ); } + + function cancelStream(ISablierV2LockupLinear sablier, uint256 streamId) public { + // Check if the stream is still active + if (!sablier.isCancelable(streamId)) { + return; + } + + IAvatar(msg.sender).execTransactionFromModule( + address(sablier), + 0, + abi.encodeWithSignature( + "cancel(uint256)", + streamId, + ), + Enum.Operation.Call + ); + } } From bf0fa435ef3e1f44515b81aee7e5ff80f68b4250 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:52:42 -0400 Subject: [PATCH 036/206] revert DecentHats_0_1_0 contract --- contracts/DecentHats_0_1_0.sol | 93 ++-------------------------------- 1 file changed, 4 insertions(+), 89 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index ced33ddc..5d29a42e 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -9,9 +9,6 @@ import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/IHats.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; -import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; -import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; -import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; contract DecentHats_0_1_0 { string public constant NAME = "DecentHats_0_1_0"; @@ -27,20 +24,13 @@ contract DecentHats_0_1_0 { LockupLinear.Broker broker; } - struct TermedParams { - uint128 termEndDateTs; - address[] nominatedWearers; - } - struct Hat { uint32 maxSupply; string details; string imageURI; bool isMutable; address wearer; - bool isTermed; SablierStreamParams[] sablierParams; // Optional Sablier stream parameters - TermedParams termedParams; // Optional termed parameters } struct CreateTreeParams { @@ -52,8 +42,6 @@ contract DecentHats_0_1_0 { string topHatImageURI; Hat adminHat; Hat[] hats; - IHatsModuleFactory hatsModuleFactory; - address hatsElectionEligibilityImplementation; } function getSalt() internal view returns (bytes32 salt) { @@ -103,7 +91,6 @@ contract DecentHats_0_1_0 { adminHatId, _hat.details, _hat.maxSupply, - // ? @todo should be this be dead HATS address? topHatAccount, topHatAccount, _hat.isMutable, @@ -158,27 +145,10 @@ contract DecentHats_0_1_0 { address topHatAccount, IERC6551Registry registry, address hatsAccountImplementation, - bytes32 salt, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionEligibilityImplementation, - uint256 topHatId + bytes32 salt ) internal returns (uint256 hatId, address accountAddress) { hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); - if (hat.isTermed) { - // Create election module and set as eligiblity, elect, and start next term - createElectionModuleAndExecuteFirstTerm( - hatsProtocol, - hatsModuleFactory, - hatsElectionEligibilityImplementation, - hatId, - hat.termedParams.termEndDateTs, - hat.termedParams.nominatedWearers, - abi.encodePacked(topHatId), - uint256(salt) - ); - } - accountAddress = createAccount( registry, hatsAccountImplementation, @@ -235,58 +205,6 @@ contract DecentHats_0_1_0 { } } - function createAdminHatAndAccount( - IHats hatsProtocol, - uint256 adminHatId, - Hat calldata hat, - address topHatAccount, - IERC6551Registry registry, - address hatsAccountImplementation, - bytes32 salt - ) internal returns (uint256 hatId, address accountAddress) { - hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); - - accountAddress = createAccount( - registry, - hatsAccountImplementation, - salt, - address(hatsProtocol), - hatId - ); - - hatsProtocol.mintHat( - hatId, - address(new DecentAutonomousAdmin("0_0_1", adminHatId)) - ); - } - - function createElectionModuleAndExecuteFirstTerm( - IHats hatsProtocol, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionEligibilityImplementation, - uint256 hatId, - uint128 termEndDateTs, - address[] memory nominatedWearer, - bytes memory otherImmutableArgs, - uint256 saltNonce - ) internal returns (address) { - address electionModuleAddress = hatsModuleFactory.createHatsModule( - hatsElectionEligibilityImplementation, - hatId, - otherImmutableArgs, - abi.encode(termEndDateTs), - saltNonce - ); - hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); - - IHatsElectionEligibility(electionModuleAddress).elect( - termEndDateTs, - nominatedWearer - ); - IHatsElectionEligibility(electionModuleAddress).startNextTerm(); - return electionModuleAddress; - } - function createAndDeclareTree(CreateTreeParams calldata params) public { bytes32 salt = getSalt(); @@ -301,7 +219,7 @@ contract DecentHats_0_1_0 { updateKeyValuePairs(params.keyValuePairs, topHatId); - (uint256 adminHatId, ) = createAdminHatAndAccount( + (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams( params.hatsProtocol, topHatId, params.adminHat, @@ -319,10 +237,7 @@ contract DecentHats_0_1_0 { topHatAccount, params.registry, params.hatsAccountImplementation, - salt, - params.hatsModuleFactory, - params.hatsElectionEligibilityImplementation, - topHatId + salt ); unchecked { @@ -332,4 +247,4 @@ contract DecentHats_0_1_0 { params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); } -} +} \ No newline at end of file From b4722373748bb0797d7d8925d19b0d4e43fe05b3 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:53:27 -0400 Subject: [PATCH 037/206] remove versioning from constructor --- contracts/DecentAutonomousAdmin.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index f228f346..ce23043a 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -6,7 +6,8 @@ import "./interfaces/sablier/ISablierV2LockupLinear.sol"; contract DecentAutonomousAdmin { string public constant NAME = "DecentAutonomousAdmin"; - string public version_; + string public version_ = "0.1.0"; + uint256 public adminHatId; struct SablierStreamInfo { @@ -24,8 +25,7 @@ contract DecentAutonomousAdmin { // ////////////////////////////////////////////////////////////// // Constructor // ////////////////////////////////////////////////////////////// - constructor(string memory _version, uint256 _adminHatId) { - version_ = _version; + constructor(uint256 _adminHatId) { adminHatId = _adminHatId; } From 6c83f8c5a16ab6291d9dde769183b51a4dadbd7a Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:56:39 -0400 Subject: [PATCH 038/206] remove unneeded deploy file --- deploy/core/018_deploy_DecentAutonomousAdmin.ts | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 deploy/core/018_deploy_DecentAutonomousAdmin.ts diff --git a/deploy/core/018_deploy_DecentAutonomousAdmin.ts b/deploy/core/018_deploy_DecentAutonomousAdmin.ts deleted file mode 100644 index cbdb509d..00000000 --- a/deploy/core/018_deploy_DecentAutonomousAdmin.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; - -const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentAutonomousAdmin", ["0.1.0"]); -}; - -export default func; From be65d3bc941778acb1d705b553e84f8d4cd7fc1b Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:59:06 -0400 Subject: [PATCH 039/206] add DecentHats_0_2_0 contract and deployment script --- contracts/DecentHats_0_2_0.sol | 355 +++++++++++++++++++++ deploy/core/018_deploy_DecentHats_0_2_0.ts | 9 + 2 files changed, 364 insertions(+) create mode 100644 contracts/DecentHats_0_2_0.sol create mode 100644 deploy/core/018_deploy_DecentHats_0_2_0.ts diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol new file mode 100644 index 00000000..3d353fd4 --- /dev/null +++ b/contracts/DecentHats_0_2_0.sol @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: MIT +pragma solidity =0.8.19; + +import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; +import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; +import {IHats} from "./interfaces/hats/IHats.sol"; +import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; +import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; +import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; +import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; +import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; + +contract DecentHats_0_2_0 { + string public constant NAME = "DecentHats_0_2_0"; + + struct SablierStreamParams { + ISablierV2LockupLinear sablier; + address sender; + uint128 totalAmount; + address asset; + bool cancelable; + bool transferable; + LockupLinear.Timestamps timestamps; + LockupLinear.Broker broker; + } + + struct TermedParams { + uint128 termEndDateTs; + address[] nominatedWearers; + } + + struct Hat { + uint32 maxSupply; + string details; + string imageURI; + bool isMutable; + address wearer; + bool isTermed; + SablierStreamParams[] sablierParams; // Optional Sablier stream parameters + TermedParams[] termedParams; // Optional termed parameters + } + + struct CreateTreeParams { + IHats hatsProtocol; + address hatsAccountImplementation; + IERC6551Registry registry; + address keyValuePairs; + string topHatDetails; + string topHatImageURI; + Hat adminHat; + Hat[] hats; + IHatsModuleFactory hatsModuleFactory; + address hatsElectionEligibilityImplementation; + } + + /* ///////////////////////////////////////////////////////////////////////////// + EXTERNAL FUNCTIONS + ///////////////////////////////////////////////////////////////////////////// */ + function createAndDeclareTree(CreateTreeParams calldata params) public { + bytes32 salt = _getSalt(); + + (uint256 topHatId, address topHatAccount) = _createTopHatAndAccount( + params.hatsProtocol, + params.topHatDetails, + params.topHatImageURI, + params.registry, + params.hatsAccountImplementation, + salt + ); + + _updateKeyValuePairs(params.keyValuePairs, topHatId); + + (uint256 adminHatId, ) = _createAdminHatAndAccount( + params.hatsProtocol, + topHatId, + params.adminHat, + topHatAccount, + params.registry, + params.hatsAccountImplementation, + salt + ); + + for (uint256 i = 0; i < params.hats.length; ) { + (uint256 hatId, ) = _createHatAndAccountAndMintAndStreams( + params.hatsProtocol, + params.registry, + topHatAccount, + params.hatsAccountImplementation, + adminHatId, + params.hats[i], + salt + ); + + if (params.hats[i].isTermed) { + // Create election module and set as eligiblity, elect, and start next term + _createElectionModuleAndExecuteFirstTerm( + params.hatsProtocol, + params.hatsModuleFactory, + params.hatsElectionEligibilityImplementation, + hatId, + topHatId, + params.hats[i].termedParams[0], + uint256(keccak256(abi.encode(salt, hatId))) + ); + } + + unchecked { + ++i; + } + } + + params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); + } + + /* ///////////////////////////////////////////////////////////////////////////// + INTERAL FUNCTIONS + ///////////////////////////////////////////////////////////////////////////// */ + + function _getSalt() internal view returns (bytes32 salt) { + uint256 chainId; + assembly { + chainId := chainid() + } + + bytes memory concatenatedSaltInput = abi.encodePacked( + NAME, + chainId, + address(this) + ); + + salt = keccak256(concatenatedSaltInput); + } + + function _updateKeyValuePairs( + address _keyValuePairs, + uint256 topHatId + ) internal { + string[] memory keys = new string[](1); + string[] memory values = new string[](1); + keys[0] = "topHatId"; + values[0] = Strings.toString(topHatId); + + IAvatar(msg.sender).execTransactionFromModule( + _keyValuePairs, + 0, + abi.encodeWithSignature( + "updateValues(string[],string[])", + keys, + values + ), + Enum.Operation.Call + ); + } + + function _createHat( + IHats _hatsProtocol, + uint256 adminHatId, + Hat memory _hat, + address topHatAccount + ) internal returns (uint256) { + return + _hatsProtocol.createHat( + adminHatId, + _hat.details, + _hat.maxSupply, + topHatAccount, + topHatAccount, + _hat.isMutable, + _hat.imageURI + ); + } + + function _createAccount( + IERC6551Registry _registry, + address _hatsAccountImplementation, + bytes32 salt, + address protocolAddress, + uint256 hatId + ) internal returns (address) { + return + _registry.createAccount( + _hatsAccountImplementation, + salt, + block.chainid, + protocolAddress, + hatId + ); + } + + function _createTopHatAndAccount( + IHats _hatsProtocol, + string memory _topHatDetails, + string memory _topHatImageURI, + IERC6551Registry _registry, + address _hatsAccountImplementation, + bytes32 salt + ) internal returns (uint256 topHatId, address topHatAccount) { + topHatId = _hatsProtocol.mintTopHat( + address(this), + _topHatDetails, + _topHatImageURI + ); + + topHatAccount = _createAccount( + _registry, + _hatsAccountImplementation, + salt, + address(_hatsProtocol), + topHatId + ); + } + + function _createHatAndAccountAndMintAndStreams( + IHats hatsProtocol, + IERC6551Registry registry, + address topHatAccount, + address hatsAccountImplementation, + uint256 adminHatId, + Hat calldata hat, + bytes32 salt + ) internal returns (uint256 hatId, address accountAddress) { + hatId = _createHat(hatsProtocol, adminHatId, hat, topHatAccount); + + accountAddress = _createAccount( + registry, + hatsAccountImplementation, + salt, + address(hatsProtocol), + hatId + ); + if (hat.wearer != address(0)) { + hatsProtocol.mintHat(hatId, hat.wearer); + } + + for (uint256 i = 0; i < hat.sablierParams.length; ) { + SablierStreamParams memory sablierParams = hat.sablierParams[i]; + + // Approve tokens for Sablier + IAvatar(msg.sender).execTransactionFromModule( + sablierParams.asset, + 0, + abi.encodeWithSignature( + "approve(address,uint256)", + address(sablierParams.sablier), + sablierParams.totalAmount + ), + Enum.Operation.Call + ); + + LockupLinear.CreateWithTimestamps memory params = LockupLinear + .CreateWithTimestamps({ + sender: sablierParams.sender, + recipient: accountAddress, + totalAmount: sablierParams.totalAmount, + asset: IERC20(sablierParams.asset), + cancelable: sablierParams.cancelable, + transferable: sablierParams.transferable, + timestamps: sablierParams.timestamps, + broker: sablierParams.broker + }); + + // Proxy the Sablier call through IAvatar + IAvatar(msg.sender).execTransactionFromModule( + address(sablierParams.sablier), + 0, + abi.encodeWithSignature( + "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", + params + ), + Enum.Operation.Call + ); + + unchecked { + ++i; + } + } + } + + function _createAdminHatAndAccount( + IHats hatsProtocol, + uint256 topHatId, + Hat calldata hat, + address topHatAccount, + IERC6551Registry registry, + address hatsAccountImplementation, + bytes32 salt + ) internal returns (uint256 adminHatId, address accountAddress) { + adminHatId = _createHat(hatsProtocol, topHatId, hat, topHatAccount); + + accountAddress = _createAccount( + registry, + hatsAccountImplementation, + salt, + address(hatsProtocol), + adminHatId + ); + address adminInstance = _deployDecentAutonomousAdmin(salt, topHatId); + hatsProtocol.mintHat(adminHatId, adminInstance); + } + + function _deployDecentAutonomousAdmin( + bytes32 salt, + uint256 _adminHatId + ) internal returns (address deployedAddress) { + bytes memory creationCode = _getCreationCode(_adminHatId); + + assembly { + deployedAddress := create2( + 0, + add(creationCode, 0x20), + mload(creationCode), + salt + ) + } + + require(deployedAddress != address(0), "CREATE2: Failed on deploy"); + } + + function _getCreationCode( + uint256 _adminHatId + ) internal pure returns (bytes memory) { + bytes memory bytecode = type(DecentAutonomousAdmin).creationCode; + bytes memory constructorArgs = abi.encode(_adminHatId); + return abi.encodePacked(bytecode, constructorArgs); + } + + function _createElectionModuleAndExecuteFirstTerm( + IHats hatsProtocol, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionEligibilityImplementation, + uint256 hatId, + uint256 topHatId, + TermedParams calldata termedParams, + uint256 saltNonce + ) internal returns (address) { + address electionModuleAddress = hatsModuleFactory.createHatsModule( + hatsElectionEligibilityImplementation, + hatId, + abi.encode(topHatId, uint256(0)), + abi.encode(termedParams.termEndDateTs), + saltNonce + ); + hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); + + IHatsElectionEligibility(electionModuleAddress).elect( + termedParams.termEndDateTs, + termedParams.nominatedWearers + ); + + return electionModuleAddress; + } +} diff --git a/deploy/core/018_deploy_DecentHats_0_2_0.ts b/deploy/core/018_deploy_DecentHats_0_2_0.ts new file mode 100644 index 00000000..9122e65e --- /dev/null +++ b/deploy/core/018_deploy_DecentHats_0_2_0.ts @@ -0,0 +1,9 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + await deployNonUpgradeable(hre, "DecentHats_0_2_0", ["0.2.0"]); +}; + +export default func; From 558b3b72f945887aafcb6c48c59be6943587b56f Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:06:42 -0400 Subject: [PATCH 040/206] reorder structs for gas efficiency --- contracts/DecentHats_0_2_0.sol | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index 3d353fd4..7286aa80 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -19,12 +19,12 @@ contract DecentHats_0_2_0 { struct SablierStreamParams { ISablierV2LockupLinear sablier; address sender; - uint128 totalAmount; address asset; - bool cancelable; - bool transferable; LockupLinear.Timestamps timestamps; LockupLinear.Broker broker; + uint128 totalAmount; + bool cancelable; + bool transferable; } struct TermedParams { @@ -33,27 +33,27 @@ contract DecentHats_0_2_0 { } struct Hat { - uint32 maxSupply; + address wearer; string details; string imageURI; + SablierStreamParams[] sablierParams; + TermedParams[] termedParams; + uint32 maxSupply; bool isMutable; - address wearer; bool isTermed; - SablierStreamParams[] sablierParams; // Optional Sablier stream parameters - TermedParams[] termedParams; // Optional termed parameters } struct CreateTreeParams { IHats hatsProtocol; - address hatsAccountImplementation; IERC6551Registry registry; + IHatsModuleFactory hatsModuleFactory; + address hatsAccountImplementation; address keyValuePairs; - string topHatDetails; - string topHatImageURI; + address hatsElectionEligibilityImplementation; Hat adminHat; Hat[] hats; - IHatsModuleFactory hatsModuleFactory; - address hatsElectionEligibilityImplementation; + string topHatDetails; + string topHatImageURI; } /* ///////////////////////////////////////////////////////////////////////////// From 26d843fbb95f7600960313aaa59c1af83a6c28b4 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:19:01 -0400 Subject: [PATCH 041/206] revert 0_1_0 test and add 0_2_0 tests --- test/DecentHats_0_1_0.test.ts | 68 ---- test/DecentHats_0_2_0.test.ts | 656 ++++++++++++++++++++++++++++++++++ 2 files changed, 656 insertions(+), 68 deletions(-) create mode 100644 test/DecentHats_0_2_0.test.ts diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index e93af2f8..c9a8352d 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -15,8 +15,6 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, - MockHatsModuleFactory__factory, - MockHatsElectionEligibility__factory, } from "../typechain-types" import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" @@ -93,9 +91,6 @@ describe("DecentHats_0_1_0", () => { let mockERC20: MockERC20 let mockERC20Address: string - let mockHatsElectionEligibilityImplementationAddress: string - let mockHatsModuleFactoryAddress: string - beforeEach(async () => { const signers = await hre.ethers.getSigners() const [deployer] = signers @@ -103,12 +98,6 @@ describe("DecentHats_0_1_0", () => { mockHats = await new MockHats__factory(deployer).deploy() mockHatsAddress = await mockHats.getAddress() - const mockHatsElectionEligibilityImplementation = - await new MockHatsElectionEligibility__factory(deployer).deploy() - mockHatsElectionEligibilityImplementationAddress = - await mockHatsElectionEligibilityImplementation.getAddress() - const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy() - mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress() keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() @@ -209,11 +198,6 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, hats: [ { @@ -223,11 +207,6 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, { maxSupply: 1, @@ -236,16 +215,8 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, ], - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -293,16 +264,8 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, hats: [], - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -393,11 +356,6 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, hats: [ { @@ -422,11 +380,6 @@ describe("DecentHats_0_1_0", () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, { maxSupply: 1, @@ -435,16 +388,8 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, ], - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, }, ] ), @@ -527,11 +472,6 @@ describe("DecentHats_0_1_0", () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, hats: [ { @@ -570,16 +510,8 @@ describe("DecentHats_0_1_0", () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], - isTermed: false, - termedParams: { - termEndDateTs: 0, - nominatedWearers: [], - }, }, ], - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, }, ] ), diff --git a/test/DecentHats_0_2_0.test.ts b/test/DecentHats_0_2_0.test.ts new file mode 100644 index 00000000..fb530edb --- /dev/null +++ b/test/DecentHats_0_2_0.test.ts @@ -0,0 +1,656 @@ +import { + GnosisSafeL2, + GnosisSafeL2__factory, + DecentHats_0_2_0__factory, + KeyValuePairs, + KeyValuePairs__factory, + MockHats__factory, + ERC6551Registry__factory, + MockHatsAccount__factory, + ERC6551Registry, + DecentHats_0_2_0, + MockHatsAccount, + MockHats, + MockSablierV2LockupLinear__factory, + MockSablierV2LockupLinear, + MockERC20__factory, + MockERC20, + MockHatsModuleFactory__factory, + MockHatsElectionEligibility__factory, +} from "../typechain-types" + +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" +import { expect } from "chai" +import { ethers, solidityPackedKeccak256 } from "ethers" +import hre from "hardhat" + +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test" +import { + buildSafeTransaction, + buildSignatureBytes, + predictGnosisSafeAddress, + safeSignTypedData, +} from "./helpers" + +const executeSafeTransaction = async ({ + safe, + to, + transactionData, + signers, +}: { + safe: GnosisSafeL2 + to: string + transactionData: string + signers: SignerWithAddress[] +}) => { + const safeTx = buildSafeTransaction({ + to, + data: transactionData, + nonce: await safe.nonce(), + }) + + const sigs = await Promise.all( + signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx)) + ) + + const tx = await safe.execTransaction( + safeTx.to, + safeTx.value, + safeTx.data, + safeTx.operation, + safeTx.safeTxGas, + safeTx.baseGas, + safeTx.gasPrice, + safeTx.gasToken, + safeTx.refundReceiver, + buildSignatureBytes(sigs) + ) + + return tx +} + +describe("DecentHats_0_2_0", () => { + let dao: SignerWithAddress + + let mockHats: MockHats + let mockHatsAddress: string + + let keyValuePairs: KeyValuePairs + let gnosisSafe: GnosisSafeL2 + + let decentHats: DecentHats_0_2_0 + let decentHatsAddress: string + + let gnosisSafeAddress: string + let erc6551Registry: ERC6551Registry + + let mockHatsAccountImplementation: MockHatsAccount + let mockHatsAccountImplementationAddress: string + + let mockSablier: MockSablierV2LockupLinear + let mockSablierAddress: string + + let mockERC20: MockERC20 + let mockERC20Address: string + + let mockHatsElectionEligibilityImplementationAddress: string + let mockHatsModuleFactoryAddress: string + + beforeEach(async () => { + const signers = await hre.ethers.getSigners() + const [deployer] = signers + ;[, dao] = signers + + mockHats = await new MockHats__factory(deployer).deploy() + mockHatsAddress = await mockHats.getAddress() + const mockHatsElectionEligibilityImplementation = + await new MockHatsElectionEligibility__factory(deployer).deploy() + mockHatsElectionEligibilityImplementationAddress = + await mockHatsElectionEligibilityImplementation.getAddress() + const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy() + mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress() + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress() + decentHats = await new DecentHats_0_2_0__factory(deployer).deploy() + decentHatsAddress = await decentHats.getAddress() + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory() + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton() + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress() + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + "setup", + [ + [dao.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ] + ) + + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`) + + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( + createGnosisSetupCalldata, + saltNum, + gnosisSafeL2SingletonAddress, + gnosisSafeProxyFactory + ) + gnosisSafeAddress = predictedGnosisSafeAddress + + await gnosisSafeProxyFactory.createProxyWithNonce( + gnosisSafeL2SingletonAddress, + createGnosisSetupCalldata, + saltNum + ) + + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer) + + // Deploy MockSablierV2LockupLinear + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy() + mockSablierAddress = await mockSablier.getAddress() + + mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK") + mockERC20Address = await mockERC20.getAddress() + + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")) + }) + + describe("DecentHats as a Module", () => { + let enableModuleTx: ethers.ContractTransactionResponse + + beforeEach(async () => { + enableModuleTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: gnosisSafeAddress, + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( + "enableModule", + [decentHatsAddress] + ), + signers: [dao], + }) + }) + + it("Emits an ExecutionSuccess event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) + + it("Emits an EnabledModule event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentHatsAddress) + }) + + describe("Creating a new Top Hat and Tree", () => { + let createAndDeclareTreeTx: ethers.ContractTransactionResponse + + beforeEach(async () => { + createAndDeclareTreeTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + hats: [ + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + }, + ] + ), + signers: [dao], + }) + }) + + it("Emits an ExecutionSuccess event", async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(createAndDeclareTreeTx) + .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .withArgs(decentHatsAddress) + }) + + it("Emits some hatsTreeId ValueUpdated events", async () => { + await expect(createAndDeclareTreeTx) + .to.emit(keyValuePairs, "ValueUpdated") + .withArgs(gnosisSafeAddress, "topHatId", "0") + }) + + describe("Multiple calls", () => { + let createAndDeclareTreeTx2: ethers.ContractTransactionResponse + + beforeEach(async () => { + createAndDeclareTreeTx2 = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + hats: [], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + }, + ] + ), + signers: [dao], + }) + }) + + it("Emits an ExecutionSuccess event", async () => { + await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, "ExecutionSuccess") + }) + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(createAndDeclareTreeTx2) + .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .withArgs(decentHatsAddress) + }) + + it("Creates Top Hats with sequential IDs", async () => { + await expect(createAndDeclareTreeTx2) + .to.emit(keyValuePairs, "ValueUpdated") + .withArgs(gnosisSafeAddress, "topHatId", "4") + }) + }) + + describe("Creating Hats Accounts", () => { + let salt: string + + beforeEach(async () => { + salt = solidityPackedKeccak256( + ["string", "uint256", "address"], + ["DecentHats_0_2_0", await hre.getChainId(), decentHatsAddress] + ) + }) + + const getHatAccount = async (hatId: bigint) => { + const hatAccountAddress = await erc6551Registry.account( + mockHatsAccountImplementationAddress, + salt, + await hre.getChainId(), + mockHatsAddress, + hatId + ) + + const hatAccount = MockHatsAccount__factory.connect( + hatAccountAddress, + hre.ethers.provider + ) + + return hatAccount + } + + it("Generates the correct Addresses for the current Hats", async () => { + const currentCount = await mockHats.count() + + for (let i = 0n; i < currentCount; i++) { + const topHatAccount = await getHatAccount(i) + expect(await topHatAccount.tokenId()).eq(i) + expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress) + } + }) + }) + }) + + describe("Creating a new Top Hat and Tree with Sablier Streams", () => { + let createAndDeclareTreeTx: ethers.ContractTransactionResponse + let currentBlockTimestamp: number + + beforeEach(async () => { + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp + + createAndDeclareTreeTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + hats: [ + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + }, + ] + ), + signers: [dao], + }) + }) + + it("Emits an ExecutionSuccess event", async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(createAndDeclareTreeTx) + .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .withArgs(decentHatsAddress) + }) + + it("Emits some hatsTreeId ValueUpdated events", async () => { + await expect(createAndDeclareTreeTx) + .to.emit(keyValuePairs, "ValueUpdated") + .withArgs(gnosisSafeAddress, "topHatId", "0") + }) + + it("Creates a Sablier stream for the hat with stream parameters", async () => { + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ) + expect(streamCreatedEvents.length).to.equal(1) + + const event = streamCreatedEvents[0] + expect(event.args.sender).to.equal(gnosisSafeAddress) + expect(event.args.recipient).to.not.equal(ethers.ZeroAddress) + expect(event.args.totalAmount).to.equal(ethers.parseEther("100")) + }) + + it("Does not create a Sablier stream for hats without stream parameters", async () => { + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ) + expect(streamCreatedEvents.length).to.equal(1) // Only one stream should be created + }) + + it("Creates a Sablier stream with correct timestamps", async () => { + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ) + expect(streamCreatedEvents.length).to.equal(1) + + const streamId = streamCreatedEvents[0].args.streamId + const stream = await mockSablier.getStream(streamId) + + expect(stream.startTime).to.equal(currentBlockTimestamp) + expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000) + }) + }) + + describe("Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat", () => { + let currentBlockTimestamp: number + + beforeEach(async () => { + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp + + await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + hats: [ + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("50"), + asset: mockERC20Address, + cancelable: false, + transferable: true, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, // No cliff + end: currentBlockTimestamp + 1296000, // 15 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + isTermed: false, + termedParams: [ + { + termEndDateTs: 0, + nominatedWearers: [], + }, + ], + }, + ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + }, + ] + ), + signers: [dao], + }) + }) + + it("Creates multiple Sablier streams for a single hat", async () => { + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ) + expect(streamCreatedEvents.length).to.equal(2) + + const event1 = streamCreatedEvents[0] + expect(event1.args.sender).to.equal(gnosisSafeAddress) + expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress) + expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")) + + const event2 = streamCreatedEvents[1] + expect(event2.args.sender).to.equal(gnosisSafeAddress) + expect(event2.args.recipient).to.equal(event1.args.recipient) + expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")) + }) + + it("Creates streams with correct parameters", async () => { + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ) + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) + expect(stream1.cancelable).to.be.true + expect(stream1.transferable).to.be.false + expect(stream1.endTime - stream1.startTime).to.equal(2592000) + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) + expect(stream2.cancelable).to.be.false + expect(stream2.transferable).to.be.true + expect(stream2.endTime - stream2.startTime).to.equal(1296000) + }) + + it("Creates streams with correct timestamps", async () => { + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ) + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) + expect(stream1.startTime).to.equal(currentBlockTimestamp) + expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000) + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) + expect(stream2.startTime).to.equal(currentBlockTimestamp) + expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000) + }) + }) + }) +}) From 0d410232bf9389b3d06494954bb3b670e55c6780 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 15:33:17 -0400 Subject: [PATCH 042/206] update test --- test/DecentAutonomousAdmin.test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index 7dcadc64..62082fbb 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -1,4 +1,3 @@ -import { ModuleProxyFactory } from "../typechain-types/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory" import { DecentAutonomousAdmin, DecentAutonomousAdmin__factory, @@ -6,7 +5,6 @@ import { MockHatsAutoAdmin__factory, MockHatsElectionEligibility, MockHatsElectionEligibility__factory, - ModuleProxyFactory__factory, } from "../typechain-types" import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" @@ -23,8 +21,6 @@ describe("DecentAutonomousAdminHat", function () { let hatsProtocol: MockHatsAutoAdmin let hatsElectionModule: MockHatsElectionEligibility let adminHat: DecentAutonomousAdmin - let adminHatMasterCopy: DecentAutonomousAdmin - let moduleProxyFactory: ModuleProxyFactory // Variables let userHatId: bigint @@ -33,7 +29,6 @@ describe("DecentAutonomousAdminHat", function () { // Get signers ;[deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners() - moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() // Deploy MockHatsAutoAdmin (Mock Hats Protocol) hatsProtocol = await new MockHatsAutoAdmin__factory(deployer).deploy() @@ -54,7 +49,7 @@ describe("DecentAutonomousAdminHat", function () { const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0] // Deploy DecentAutonomousAdminHat contract with the admin hat ID - adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy("TEST", adminHatId) + adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy(adminHatId) const adminHatAddress = await adminHat.getAddress() // Mint the admin hat to adminHatWearer await hatsProtocol.mintHat(adminHatId, adminHatAddress) From 1bafbf844a258db50bf78e209cbf62e197c065cf Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 7 Oct 2024 22:46:39 -0400 Subject: [PATCH 043/206] fix deployment script --- deploy/core/018_deploy_DecentHats_0_2_0.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/core/018_deploy_DecentHats_0_2_0.ts b/deploy/core/018_deploy_DecentHats_0_2_0.ts index 9122e65e..66da759a 100644 --- a/deploy/core/018_deploy_DecentHats_0_2_0.ts +++ b/deploy/core/018_deploy_DecentHats_0_2_0.ts @@ -3,7 +3,7 @@ import { DeployFunction } from "hardhat-deploy/types"; import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentHats_0_2_0", ["0.2.0"]); + await deployNonUpgradeable(hre, "DecentHats_0_2_0"); }; export default func; From da60def6f7c9864b12b6ab767b7c729bb9f89f8a Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 8 Oct 2024 14:27:40 +0100 Subject: [PATCH 044/206] Add (probably inaccurate) withdrawMaxFromStream tests --- ....sol => DecentSablierStreamManagement.sol} | 27 +- .../interfaces/sablier/ISablierV2Lockup.sol | 13 +- contracts/mocks/MockSablier.sol | 34 -- contracts/mocks/MockSablierV2LockupLinear.sol | 47 +- test/DecentHats_0_1_0.test.ts | 518 +++++++----------- test/DecentSablierStreamManagement.test.ts | 302 ++++++++++ test/DecentSablier_0_1_0.test.ts | 143 ----- test/helpers.ts | 128 +++-- 8 files changed, 623 insertions(+), 589 deletions(-) rename contracts/{DecentSablier_0_1_0.sol => DecentSablierStreamManagement.sol} (69%) delete mode 100644 contracts/mocks/MockSablier.sol create mode 100644 test/DecentSablierStreamManagement.test.ts delete mode 100644 test/DecentSablier_0_1_0.test.ts diff --git a/contracts/DecentSablier_0_1_0.sol b/contracts/DecentSablierStreamManagement.sol similarity index 69% rename from contracts/DecentSablier_0_1_0.sol rename to contracts/DecentSablierStreamManagement.sol index 8bcbeefd..7528b255 100644 --- a/contracts/DecentSablier_0_1_0.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -10,9 +10,8 @@ contract DecentSablierStreamManagement { function withdrawMaxFromStream( ISablierV2LockupLinear sablier, - HatsAccount1ofNAbi smartAccount, uint256 streamId, - address to, + address to ) public { // Check if there are funds to withdraw uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId); @@ -22,24 +21,21 @@ contract DecentSablierStreamManagement { // Proxy the Sablier withdrawMax call through IAvatar (Safe) IAvatar(msg.sender).execTransactionFromModule( - address(smartAccount), + address(sablier), 0, abi.encodeWithSignature( - "execute(address,uint256,bytes,uint8)", - address(sablier), - 0, - abi.encodeWithSignature( - "withdrawMax(uint256,address)", - streamId, - to - ), - 0 + "withdrawMax(uint256,address)", + streamId, + to ), Enum.Operation.Call ); } - function cancelStream(ISablierV2LockupLinear sablier, uint256 streamId) public { + function cancelStream( + ISablierV2LockupLinear sablier, + uint256 streamId + ) public { // Check if the stream is still active if (!sablier.isCancelable(streamId)) { return; @@ -48,10 +44,7 @@ contract DecentSablierStreamManagement { IAvatar(msg.sender).execTransactionFromModule( address(sablier), 0, - abi.encodeWithSignature( - "cancel(uint256)", - streamId, - ), + abi.encodeWithSignature("cancel(uint256)", streamId), Enum.Operation.Call ); } diff --git a/contracts/interfaces/sablier/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol index a6ee2545..124e767f 100644 --- a/contracts/interfaces/sablier/ISablierV2Lockup.sol +++ b/contracts/interfaces/sablier/ISablierV2Lockup.sol @@ -2,11 +2,16 @@ pragma solidity ^0.8.0; interface ISablierV2Lockup { - function getRecipient( - uint256 streamId - ) external view returns (address recipient); - function withdrawableAmountOf( uint256 streamId ) external view returns (uint128 withdrawableAmount); + + function isCancelable(uint256 streamId) external view returns (bool result); + + function withdrawMax( + uint256 streamId, + address to + ) external returns (uint128 withdrawnAmount); + + function cancel(uint256 streamId) external; } diff --git a/contracts/mocks/MockSablier.sol b/contracts/mocks/MockSablier.sol deleted file mode 100644 index 0d823195..00000000 --- a/contracts/mocks/MockSablier.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -contract MockSablier { - mapping(uint256 => uint256) private streamBalances; - mapping(uint256 => uint256) private withdrawnAmounts; - - function setStreamBalance(uint256 streamId, uint256 balance) external { - streamBalances[streamId] = balance; - } - - function balanceOf( - uint256 streamId, - address - ) external view returns (uint256) { - return streamBalances[streamId]; - } - - function withdrawFromStream( - uint256 streamId, - uint256 amount - ) external returns (bool) { - require(streamBalances[streamId] >= amount, "Insufficient balance"); - streamBalances[streamId] -= amount; - withdrawnAmounts[streamId] += amount; - return true; - } - - function getWithdrawnAmount( - uint256 streamId - ) external view returns (uint256) { - return withdrawnAmounts[streamId]; - } -} diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index f0ad0030..c24b136f 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -99,16 +99,21 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { ); } - function withdraw(uint256 streamId, uint128 amount) external { + function withdrawMax( + uint256 streamId, + address to + ) external returns (uint128 withdrawnAmount) { + withdrawnAmount = withdrawableAmountOf(streamId); Stream storage stream = streams[streamId]; - require(msg.sender == stream.recipient, "Only recipient can withdraw"); + + require(to == stream.recipient, "Only recipient can withdraw"); require( - amount <= withdrawableAmountOf(streamId), + withdrawnAmount <= withdrawableAmountOf(streamId), "Insufficient withdrawable amount" ); - stream.totalAmount -= amount; - IERC20(stream.asset).transfer(stream.recipient, amount); + stream.totalAmount -= withdrawnAmount; + IERC20(stream.asset).transfer(stream.recipient, withdrawnAmount); } function cancel(uint256 streamId) external { @@ -129,35 +134,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { } } - function renounce(uint256 streamId) external { - Stream memory stream = streams[streamId]; - require(msg.sender == stream.recipient, "Only recipient can renounce"); - - uint128 withdrawableAmount = withdrawableAmountOf(streamId); - uint128 refundAmount = stream.totalAmount - withdrawableAmount; - - delete streams[streamId]; - - if (withdrawableAmount > 0) { - IERC20(stream.asset).transfer(stream.recipient, withdrawableAmount); - } - if (refundAmount > 0) { - IERC20(stream.asset).transfer(stream.sender, refundAmount); - } - } - - function transferFrom(uint256 streamId, address recipient) external { - Stream storage stream = streams[streamId]; - require(stream.transferable, "Stream is not transferable"); - require( - msg.sender == stream.recipient, - "Only current recipient can transfer" - ); - - stream.recipient = recipient; - } - - function getRecipient(uint256 streamId) external view returns (address) { - return streams[streamId].recipient; + function isCancelable(uint256 streamId) external view returns (bool) { + return streams[streamId].cancelable; } } diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index afaa5c95..f0da3930 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -22,54 +22,15 @@ import { expect } from "chai"; import { ethers, solidityPackedKeccak256 } from "ethers"; import hre from "hardhat"; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, -} from "./GlobalSafeDeployments.test"; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test"; import { buildSafeTransaction, buildSignatureBytes, + executeSafeTransaction, predictGnosisSafeAddress, safeSignTypedData, } from "./helpers"; -const executeSafeTransaction = async ({ - safe, - to, - transactionData, - signers, -}: { - safe: GnosisSafeL2; - to: string; - transactionData: string; - signers: SignerWithAddress[]; -}) => { - const safeTx = buildSafeTransaction({ - to, - data: transactionData, - nonce: await safe.nonce(), - }); - - const sigs = await Promise.all( - signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx)) - ); - - const tx = await safe.execTransaction( - safeTx.to, - safeTx.value, - safeTx.data, - safeTx.operation, - safeTx.safeTxGas, - safeTx.baseGas, - safeTx.gasPrice, - safeTx.gasToken, - safeTx.refundReceiver, - buildSignatureBytes(sigs) - ); - - return tx; -}; - describe("DecentHats_0_1_0", () => { let dao: SignerWithAddress; @@ -103,34 +64,27 @@ describe("DecentHats_0_1_0", () => { mockHatsAddress = await mockHats.getAddress(); keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory( - deployer - ).deploy(); - mockHatsAccountImplementationAddress = - await mockHatsAccountImplementation.getAddress(); + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); decentHatsAddress = await decentHats.getAddress(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = - await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [dao.address], - 1, - hre.ethers.ZeroAddress, - hre.ethers.ZeroHash, - hre.ethers.ZeroAddress, - hre.ethers.ZeroAddress, - 0, - hre.ethers.ZeroAddress, - ]); - - const saltNum = BigInt( - `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` - ); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + [dao.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ]); + + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`); const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, @@ -140,56 +94,42 @@ describe("DecentHats_0_1_0", () => { ); gnosisSafeAddress = predictedGnosisSafeAddress; - await gnosisSafeProxyFactory.createProxyWithNonce( - gnosisSafeL2SingletonAddress, - createGnosisSetupCalldata, - saltNum - ); + await gnosisSafeProxyFactory.createProxyWithNonce(gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, saltNum); - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory( - deployer - ).deploy(); + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); mockSablierAddress = await mockSablier.getAddress(); - mockERC20 = await new MockERC20__factory(deployer).deploy( - "MockERC20", - "MCK" - ); + mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK"); mockERC20Address = await mockERC20.getAddress(); await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); }); - describe("DecentHats as a Module", () => { + describe("DecentHats", () => { let enableModuleTx: ethers.ContractTransactionResponse; beforeEach(async () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: - GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentHatsAddress] - ), + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData("enableModule", [ + decentHatsAddress, + ]), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); - }); + describe("Enabled as a module", () => { + it("Emits an ExecutionSuccess event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); - it("Emits an EnabledModule event", async () => { - await expect(enableModuleTx) - .to.emit(gnosisSafe, "EnabledModule") - .withArgs(decentHatsAddress); + it("Emits an EnabledModule event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentHatsAddress); + }); }); describe("Creating a new Top Hat and Tree", () => { @@ -199,56 +139,48 @@ describe("DecentHats_0_1_0", () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], }, - ] - ), + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + ], + }, + ]), signers: [dao], }); }); it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess"); }); it("Emits an ExecutionFromModuleSuccess event", async () => { @@ -270,39 +202,31 @@ describe("DecentHats_0_1_0", () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], - }, - ] - ), + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [], + }, + ]), signers: [dao], }); }); it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx2).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); + await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, "ExecutionSuccess"); }); it("Emits an ExecutionFromModuleSuccess event", async () => { @@ -337,10 +261,7 @@ describe("DecentHats_0_1_0", () => { hatId ); - const hatAccount = MockHatsAccount__factory.connect( - hatAccountAddress, - hre.ethers.provider - ); + const hatAccount = MockHatsAccount__factory.connect(hatAccountAddress, hre.ethers.provider); return hatAccount; }; @@ -351,9 +272,7 @@ describe("DecentHats_0_1_0", () => { for (let i = 0n; i < currentCount; i++) { const topHatAccount = await getHatAccount(i); expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq( - mockHatsAddress - ); + expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); } }); }); @@ -364,77 +283,68 @@ describe("DecentHats_0_1_0", () => { let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp; createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], }, - ] - ), + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + ], + }, + ]), signers: [dao], }); }); it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess"); }); it("Emits an ExecutionFromModuleSuccess event", async () => { @@ -450,9 +360,7 @@ describe("DecentHats_0_1_0", () => { }); it("Creates a Sablier stream for the hat with stream parameters", async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); expect(streamCreatedEvents.length).to.equal(1); const event = streamCreatedEvents[0]; @@ -462,16 +370,12 @@ describe("DecentHats_0_1_0", () => { }); it("Does not create a Sablier stream for hats without stream parameters", async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created }); it("Creates a Sablier stream with correct timestamps", async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); expect(streamCreatedEvents.length).to.equal(1); const streamId = streamCreatedEvents[0].args.streamId; @@ -486,82 +390,74 @@ describe("DecentHats_0_1_0", () => { let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp; await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("50"), - asset: mockERC20Address, - cancelable: false, - transferable: true, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, // No cliff - end: currentBlockTimestamp + 1296000, // 15 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("50"), + asset: mockERC20Address, + cancelable: false, + transferable: true, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, // No cliff + end: currentBlockTimestamp + 1296000, // 15 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], }, - ] - ), + ], + }, + ]), signers: [dao], }); }); it("Creates multiple Sablier streams for a single hat", async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); expect(streamCreatedEvents.length).to.equal(2); const event1 = streamCreatedEvents[0]; @@ -576,39 +472,27 @@ describe("DecentHats_0_1_0", () => { }); it("Creates streams with correct parameters", async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); expect(stream1.cancelable).to.be.true; expect(stream1.transferable).to.be.false; expect(stream1.endTime - stream1.startTime).to.equal(2592000); - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); expect(stream2.cancelable).to.be.false; expect(stream2.transferable).to.be.true; expect(stream2.endTime - stream2.startTime).to.equal(1296000); }); it("Creates streams with correct timestamps", async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); expect(stream1.startTime).to.equal(currentBlockTimestamp); expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); expect(stream2.startTime).to.equal(currentBlockTimestamp); expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); }); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts new file mode 100644 index 00000000..6d15648d --- /dev/null +++ b/test/DecentSablierStreamManagement.test.ts @@ -0,0 +1,302 @@ +import { + DecentHats_0_1_0, + DecentHats_0_1_0__factory, + DecentSablierStreamManagement, + DecentSablierStreamManagement__factory, + ERC6551Registry, + ERC6551Registry__factory, + GnosisSafeL2, + GnosisSafeL2__factory, + KeyValuePairs__factory, + MockERC20, + MockERC20__factory, + MockHats, + MockHats__factory, + MockHatsAccount, + MockHatsAccount__factory, + MockSablierV2LockupLinear, + MockSablierV2LockupLinear__factory, +} from "../typechain-types"; + +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { expect } from "chai"; +import { ethers } from "ethers"; +import hre from "hardhat"; + +import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from "./helpers"; + +import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from "./GlobalSafeDeployments.test"; + +describe.only("DecentSablierStreamManagement", () => { + let dao: SignerWithAddress; + let gnosisSafe: GnosisSafeL2; + + let mockHats: MockHats; + let mockHatsAddress: string; + + let decentHats: DecentHats_0_1_0; + let decentHatsAddress: string; + + let decentSablierManagement: DecentSablierStreamManagement; + let decentSablierManagementAddress: string; + + let mockHatsAccountImplementation: MockHatsAccount; + let mockHatsAccountImplementationAddress: string; + + let mockERC20: MockERC20; + let mockERC20Address: string; + + let gnosisSafeAddress: string; + + let mockSablier: MockSablierV2LockupLinear; + let mockSablierAddress: string; + + let erc6551Registry: ERC6551Registry; + + let currentBlockTimestamp: number; + + let streamId: ethers.BigNumberish; + + let enableModuleTx: ethers.ContractTransactionResponse; + let createAndDeclareTreeWithRolesAndStreamsTx: ethers.ContractTransactionResponse; + + beforeEach(async () => { + const signers = await hre.ethers.getSigners(); + const [deployer] = signers; + [, dao] = signers; + + decentSablierManagement = await new DecentSablierStreamManagement__factory(deployer).deploy(); + decentSablierManagementAddress = await decentSablierManagement.getAddress(); + + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); + + decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); + decentHatsAddress = await decentHats.getAddress(); + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + [dao.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ]); + + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`); + + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( + createGnosisSetupCalldata, + saltNum, + gnosisSafeL2SingletonAddress, + gnosisSafeProxyFactory + ); + gnosisSafeAddress = predictedGnosisSafeAddress; + + await gnosisSafeProxyFactory.createProxyWithNonce(gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, saltNum); + + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); + + // Deploy MockSablierV2LockupLinear + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockSablierAddress = await mockSablier.getAddress(); + + mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK"); + mockERC20Address = await mockERC20.getAddress(); + + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); + + // Set up the Safe with roles and streams + await executeSafeTransaction({ + safe: gnosisSafe, + to: gnosisSafeAddress, + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData("enableModule", [decentHatsAddress]), + signers: [dao], + }); + + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp; + + mockHats = await new MockHats__factory(deployer).deploy(); + mockHatsAddress = await mockHats.getAddress(); + let keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); + + createAndDeclareTreeWithRolesAndStreamsTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: dao.address, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + ], + }, + ]), + signers: [dao], + }); + + await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit(gnosisSafe, "ExecutionSuccess"); + await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + expect(streamCreatedEvents.length).to.equal(1); + + streamId = streamCreatedEvents[0].args.streamId; + + // Enable the module + enableModuleTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: gnosisSafeAddress, + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData("enableModule", [ + decentSablierManagementAddress, + ]), + signers: [dao], + }); + }); + + describe("Enabled as a Module", () => { + it("Emits an ExecutionSuccess event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Emits an EnabledModule event", async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentSablierManagementAddress); + }); + }); + + describe("Withdrawing From Stream", () => { + let withdrawTx: ethers.ContractTransactionResponse; + + describe("When the stream has funds", () => { + beforeEach(async () => { + // No action has been taken yet on the stream. Balance should be untouched. + expect(await mockSablier.withdrawableAmountOf(streamId)).to.not.eq(0); + + // Advance time to the end of the stream + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000]); + await hre.ethers.provider.send("evm_mine", []); + + const recipientHatAccount = await getHatAccount( + 2n, + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress, + decentHatsAddress + ); + + withdrawTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentSablierManagementAddress, + transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "withdrawMaxFromStream", + [mockSablierAddress, streamId, await recipientHatAccount.getAddress()] + ), + signers: [dao], + }); + + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2692000]); + await hre.ethers.provider.send("evm_mine", []); + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(withdrawTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(withdrawTx) + .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .withArgs(decentSablierManagementAddress); + }); + + it("Withdraws the maximum amount from the stream", async () => { + expect(await mockSablier.withdrawableAmountOf(streamId)).to.equal(0); + }); + }); + + describe("When the stream has no funds", () => { + beforeEach(async () => { + // Advance time to the end of the stream + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000]); + await hre.ethers.provider.send("evm_mine", []); + + const recipientHatAccount = await getHatAccount( + 2n, + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress, + decentHatsAddress + ); + + // The recipient withdraws the full amount + await MockSablierV2LockupLinear__factory.connect(mockSablierAddress, dao).withdrawMax( + streamId, + await recipientHatAccount.getAddress() + ); + expect(await mockSablier.withdrawableAmountOf(streamId)).to.equal(0); + + withdrawTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentSablierManagementAddress, + transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "withdrawMaxFromStream", + [mockSablierAddress, streamId, await recipientHatAccount.getAddress()] + ), + signers: [dao], + }); + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(withdrawTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(withdrawTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + }); + + it("Does not revert", async () => { + expect(withdrawTx).to.not.reverted; + }); + }); + }); +}); diff --git a/test/DecentSablier_0_1_0.test.ts b/test/DecentSablier_0_1_0.test.ts deleted file mode 100644 index 935f46f5..00000000 --- a/test/DecentSablier_0_1_0.test.ts +++ /dev/null @@ -1,143 +0,0 @@ -// import { -// GnosisSafeL2, -// GnosisSafeL2__factory, -// DecentSablier_0_1_0__factory, -// DecentSablier_0_1_0, -// } from "../typechain-types"; - -// import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -// import { expect } from "chai"; -// import { ethers } from "ethers"; -// import hre from "hardhat"; - -// import { -// getGnosisSafeL2Singleton, -// getGnosisSafeProxyFactory, -// } from "./GlobalSafeDeployments.test"; -// import { -// buildSafeTransaction, -// buildSignatureBytes, -// predictGnosisSafeAddress, -// safeSignTypedData, -// } from "./helpers"; - -// import { MockSablier__factory } from "../typechain-types"; - -// async function executeSafeTransaction({ -// safe, -// to, -// value, -// data, -// operation, -// signers, -// }: { -// safe: GnosisSafeL2; -// to: string; -// value?: bigint; -// data?: string; -// operation?: number; -// signers: SignerWithAddress[]; -// }) { -// const safeTransactionData = { -// to, -// value: value || 0n, -// data: data || "0x", -// operation: operation || 0, -// // Add the missing 'nonce' property -// nonce: await safe.nonce(), -// }; -// const safeTransaction = await buildSafeTransaction(safeTransactionData); -// const senderSignature = await safeSignTypedData( -// signers[0], -// safe, -// safeTransaction -// ); -// const signatureBytes = buildSignatureBytes([senderSignature]); -// // Change 'executeTransaction' to 'execTransaction' -// return safe.execTransaction(safeTransaction, signatureBytes); -// } - -// describe("DecentSablier", () => { -// let dao: SignerWithAddress; -// let gnosisSafe: GnosisSafeL2; -// let decentSablier: DecentSablier_0_1_0; -// let decentSablierAddress: string; -// let gnosisSafeAddress: string; - -// let mockSablier: MockSablier; - -// beforeEach(async () => { -// // ... (setup code similar to DecentHats.test.ts) -// // Deploy MockSablier -// const MockSablier = await ethers.getContractFactory("MockSablier"); -// mockSablier = await MockSablier.deploy(); -// await mockSablier.deployed(); -// }); - -// describe("DecentSablier as a Module", () => { -// let enableModuleTx: ethers.ContractTransactionResponse; - -// beforeEach(async () => { -// // ... (enable module code similar to DecentHats.test.ts) -// }); - -// it("Emits an ExecutionSuccess event", async () => { -// await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); -// }); - -// it("Emits an EnabledModule event", async () => { -// await expect(enableModuleTx) -// .to.emit(gnosisSafe, "EnabledModule") -// .withArgs(decentSablierAddress); -// }); - -// describe("Processing Sablier Streams", () => { -// let processSablierStreamsTx: ethers.ContractTransactionResponse; - -// beforeEach(async () => { -// // Set up mock stream balances -// await mockSablier.setStreamBalance(1, ethers.utils.parseEther("100")); -// await mockSablier.setStreamBalance(2, ethers.utils.parseEther("200")); -// await mockSablier.setStreamBalance(3, ethers.utils.parseEther("300")); - -// processSablierStreamsTx = await executeSafeTransaction({ -// safe: gnosisSafe, -// to: decentSablierAddress, -// data: DecentSablier_0_1_0__factory.createInterface().encodeFunctionData( -// "processSablierStreams", -// [ -// mockSablier.address, -// [{ streamId: 1 }, { streamId: 2 }, { streamId: 3 }], -// ] -// ), -// signers: [dao], -// }); -// }); - -// it("Emits an ExecutionSuccess event", async () => { -// await expect(processSablierStreamsTx).to.emit( -// gnosisSafe, -// "ExecutionSuccess" -// ); -// }); - -// it("Emits an ExecutionFromModuleSuccess event", async () => { -// await expect(processSablierStreamsTx) -// .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") -// .withArgs(decentSablierAddress); -// }); - -// it("Withdraws from streams correctly", async () => { -// expect(await mockSablier.getWithdrawnAmount(1)).to.equal( -// ethers.utils.parseEther("100") -// ); -// expect(await mockSablier.getWithdrawnAmount(2)).to.equal( -// ethers.utils.parseEther("200") -// ); -// expect(await mockSablier.getWithdrawnAmount(3)).to.equal( -// ethers.utils.parseEther("300") -// ); -// }); -// }); -// }); -// }); diff --git a/test/helpers.ts b/test/helpers.ts index 54ef666f..0e0626ff 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,10 +1,15 @@ -import { ethers } from "ethers"; +import { ethers, solidityPackedKeccak256 } from "ethers"; import { + ERC6551Registry, + GnosisSafeL2, GnosisSafeProxyFactory, IAzorius, MockContract__factory, + MockHatsAccount__factory, } from "../typechain-types"; import { getMockContract } from "./GlobalSafeDeployments.test"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import hre from "hardhat"; export interface MetaTransaction { to: string; @@ -39,10 +44,7 @@ export const predictGnosisSafeAddress = async ( ["bytes", "uint256"], [ethers.solidityPackedKeccak256(["bytes"], [calldata]), saltNum] ), - ethers.solidityPackedKeccak256( - ["bytes", "uint256"], - [await gnosisFactory.proxyCreationCode(), singleton] - ) + ethers.solidityPackedKeccak256(["bytes", "uint256"], [await gnosisFactory.proxyCreationCode(), singleton]) ); }; @@ -53,21 +55,14 @@ export const calculateProxyAddress = async ( saltNonce: string ): Promise => { const masterCopyAddress = masterCopy.toLowerCase().replace(/^0x/, ""); - const byteCode = - "0x602d8060093d393df3363d3d373d3d3d363d73" + - masterCopyAddress + - "5af43d82803e903d91602b57fd5bf3"; + const byteCode = "0x602d8060093d393df3363d3d373d3d3d363d73" + masterCopyAddress + "5af43d82803e903d91602b57fd5bf3"; const salt = ethers.solidityPackedKeccak256( ["bytes32", "uint256"], [ethers.solidityPackedKeccak256(["bytes"], [initData]), saltNonce] ); - return ethers.getCreate2Address( - await factory.getAddress(), - salt, - ethers.keccak256(byteCode) - ); + return ethers.getCreate2Address(await factory.getAddress(), salt, ethers.keccak256(byteCode)); }; export const safeSignTypedData = async ( @@ -105,9 +100,7 @@ export const safeSignTypedData = async ( }; export const buildSignatureBytes = (signatures: SafeSignature[]): string => { - signatures.sort((left, right) => - left.signer.toLowerCase().localeCompare(right.signer.toLowerCase()) - ); + signatures.sort((left, right) => left.signer.toLowerCase().localeCompare(right.signer.toLowerCase())); let signatureBytes = "0x"; for (const sig of signatures) { signatureBytes += sig.data.slice(2); @@ -179,28 +172,85 @@ export const encodeMultiSend = (txs: MetaTransaction[]): string => { ); }; -export const mockTransaction = - async (): Promise => { - return { - to: await getMockContract().getAddress(), - value: 0n, - // eslint-disable-next-line camelcase - data: MockContract__factory.createInterface().encodeFunctionData( - "doSomething" - ), - operation: 0, - }; +export const mockTransaction = async (): Promise => { + return { + to: await getMockContract().getAddress(), + value: 0n, + // eslint-disable-next-line camelcase + data: MockContract__factory.createInterface().encodeFunctionData("doSomething"), + operation: 0, }; +}; -export const mockRevertTransaction = - async (): Promise => { - return { - to: await getMockContract().getAddress(), - value: 0n, - // eslint-disable-next-line camelcase - data: MockContract__factory.createInterface().encodeFunctionData( - "revertSomething" - ), - operation: 0, - }; +export const mockRevertTransaction = async (): Promise => { + return { + to: await getMockContract().getAddress(), + value: 0n, + // eslint-disable-next-line camelcase + data: MockContract__factory.createInterface().encodeFunctionData("revertSomething"), + operation: 0, }; +}; + +export const executeSafeTransaction = async ({ + safe, + to, + transactionData, + signers, +}: { + safe: GnosisSafeL2; + to: string; + transactionData: string; + signers: SignerWithAddress[]; +}) => { + const safeTx = buildSafeTransaction({ + to, + data: transactionData, + nonce: await safe.nonce(), + }); + console.log("safeIx"); + + const sigs = await Promise.all(signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx))); + + const tx = await safe.execTransaction( + safeTx.to, + safeTx.value, + safeTx.data, + safeTx.operation, + safeTx.safeTxGas, + safeTx.baseGas, + safeTx.gasPrice, + safeTx.gasToken, + safeTx.refundReceiver, + buildSignatureBytes(sigs) + ); + + console.log("done?"); + + return tx; +}; + +export const getHatAccount = async ( + hatId: bigint, + erc6551RegistryImplementation: ERC6551Registry, + mockHatsAccountImplementationAddress: string, + mockHatsAddress: string, + decentHatsAddress: string +) => { + const salt = solidityPackedKeccak256( + ["string", "uint256", "address"], + ["DecentHats_0_1_0", await hre.getChainId(), decentHatsAddress] + ); + + const hatAccountAddress = await erc6551RegistryImplementation.account( + mockHatsAccountImplementationAddress, + salt, + await hre.getChainId(), + mockHatsAddress, + hatId + ); + + const hatAccount = MockHatsAccount__factory.connect(hatAccountAddress, hre.ethers.provider); + + return hatAccount; +}; From 01bdfd15f0fa0244feba22961f9f784cbf70c9cc Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 8 Oct 2024 15:18:34 +0100 Subject: [PATCH 045/206] Add cancel stream tests (with 1 bug) --- contracts/DecentSablierStreamManagement.sol | 5 +- .../interfaces/sablier/ISablierV2Lockup.sol | 5 + contracts/interfaces/sablier/LockupLinear.sol | 12 ++ contracts/mocks/MockSablierV2LockupLinear.sol | 27 ++-- test/DecentSablierStreamManagement.test.ts | 119 +++++++++++++++++- test/helpers.ts | 3 - 6 files changed, 147 insertions(+), 24 deletions(-) diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index 7528b255..c3157ee8 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -37,7 +37,10 @@ contract DecentSablierStreamManagement { uint256 streamId ) public { // Check if the stream is still active - if (!sablier.isCancelable(streamId)) { + if ( + !sablier.isCancelable(streamId) || + sablier.getStream(streamId).endTime < block.timestamp + ) { return; } diff --git a/contracts/interfaces/sablier/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol index 124e767f..5a55c512 100644 --- a/contracts/interfaces/sablier/ISablierV2Lockup.sol +++ b/contracts/interfaces/sablier/ISablierV2Lockup.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import {LockupLinear} from "../sablier/LockupLinear.sol"; interface ISablierV2Lockup { function withdrawableAmountOf( @@ -13,5 +14,9 @@ interface ISablierV2Lockup { address to ) external returns (uint128 withdrawnAmount); + function getStream( + uint256 streamId + ) external view returns (LockupLinear.Stream memory); + function cancel(uint256 streamId) external; } diff --git a/contracts/interfaces/sablier/LockupLinear.sol b/contracts/interfaces/sablier/LockupLinear.sol index 0225d060..3b7eb887 100644 --- a/contracts/interfaces/sablier/LockupLinear.sol +++ b/contracts/interfaces/sablier/LockupLinear.sol @@ -25,4 +25,16 @@ library LockupLinear { address account; uint256 fee; } + + struct Stream { + address sender; + address recipient; + uint128 totalAmount; + address asset; + bool cancelable; + bool transferable; + uint40 startTime; + uint40 cliffTime; + uint40 endTime; + } } diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index c24b136f..ca8e6a52 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -6,20 +6,7 @@ import "../interfaces/sablier/ISablierV2LockupLinear.sol"; import {LockupLinear} from "../interfaces/sablier/LockupLinear.sol"; contract MockSablierV2LockupLinear is ISablierV2LockupLinear { - // Define the Stream struct here - struct Stream { - address sender; - address recipient; - uint128 totalAmount; - address asset; - bool cancelable; - bool transferable; - uint40 startTime; - uint40 cliffTime; - uint40 endTime; - } - - mapping(uint256 => Stream) public streams; + mapping(uint256 => LockupLinear.Stream) public streams; uint256 public nextStreamId = 1; // Add this event declaration at the contract level @@ -49,7 +36,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { ); streamId = nextStreamId++; - streams[streamId] = Stream({ + streams[streamId] = LockupLinear.Stream({ sender: params.sender, recipient: params.recipient, totalAmount: params.totalAmount, @@ -78,14 +65,16 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { return streamId; } - function getStream(uint256 streamId) external view returns (Stream memory) { + function getStream( + uint256 streamId + ) external view returns (LockupLinear.Stream memory) { return streams[streamId]; } function withdrawableAmountOf( uint256 streamId ) public view returns (uint128) { - Stream memory stream = streams[streamId]; + LockupLinear.Stream memory stream = streams[streamId]; if (block.timestamp <= stream.startTime) { return 0; } @@ -104,7 +93,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { address to ) external returns (uint128 withdrawnAmount) { withdrawnAmount = withdrawableAmountOf(streamId); - Stream storage stream = streams[streamId]; + LockupLinear.Stream storage stream = streams[streamId]; require(to == stream.recipient, "Only recipient can withdraw"); require( @@ -117,7 +106,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { } function cancel(uint256 streamId) external { - Stream memory stream = streams[streamId]; + LockupLinear.Stream memory stream = streams[streamId]; require(stream.cancelable, "Stream is not cancelable"); require(msg.sender == stream.sender, "Only sender can cancel"); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 6d15648d..b21997ee 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -290,7 +290,7 @@ describe.only("DecentSablierStreamManagement", () => { await expect(withdrawTx).to.emit(gnosisSafe, "ExecutionSuccess"); }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it("Does not emit an ExecutionFromModuleSuccess event", async () => { await expect(withdrawTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); }); @@ -299,4 +299,121 @@ describe.only("DecentSablierStreamManagement", () => { }); }); }); + + describe("Cancelling From Stream", () => { + let cancelTx: ethers.ContractTransactionResponse; + + describe("When the stream is active", () => { + beforeEach(async () => { + // Advance time to before the end of the stream + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 60000]); // 1 minute from now + await hre.ethers.provider.send("evm_mine", []); + + cancelTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentSablierManagementAddress, + transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData("cancelStream", [ + mockSablierAddress, + streamId, + ]), + signers: [dao], + }); + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(cancelTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Emits an ExecutionFromModuleSuccess event", async () => { + await expect(cancelTx) + .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .withArgs(decentSablierManagementAddress); + }); + + it("Cancels the stream", async () => { + expect((await mockSablier.getStream(streamId)).cancelable).to.equal(false); + }); + }); + + describe("When the stream has expired", () => { + beforeEach(async () => { + // Advance time to the end of the stream + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000 + 60000]); // 30 days from now + 1 minute + await hre.ethers.provider.send("evm_mine", []); + + cancelTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentSablierManagementAddress, + transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData("cancelStream", [ + mockSablierAddress, + streamId, + ]), + signers: [dao], + }); + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(cancelTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Does not emit an ExecutionFromModuleSuccess event", async () => { + await expect(cancelTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + }); + + it("Does not revert", async () => { + expect(cancelTx).to.not.reverted; + }); + }); + + describe("When the stream has been previously cancelled", () => { + beforeEach(async () => { + // Advance time to before the end of the stream + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 120000]); // 2 minutes from now + await hre.ethers.provider.send("evm_mine", []); + + await MockSablierV2LockupLinear__factory.connect(mockSablierAddress, dao).cancel(streamId); + + const stream = await mockSablier.getStream(streamId); + + expect(stream.startTime).to.equal(currentBlockTimestamp); + expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000); + + // The safe cancels the stream + await executeSafeTransaction({ + safe: gnosisSafe, + to: mockSablierAddress, + transactionData: MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData("cancel", [ + streamId, + ]), + signers: [dao], + }); + + // advance 1 minute + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 60000]); + await hre.ethers.provider.send("evm_mine", []); + + cancelTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentSablierManagementAddress, + transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData("cancelStream", [ + mockSablierAddress, + streamId, + ]), + signers: [dao], + }); + }); + + it("Emits an ExecutionSuccess event", async () => { + await expect(cancelTx).to.emit(gnosisSafe, "ExecutionSuccess"); + }); + + it("Does not emit an ExecutionFromModuleSuccess event", async () => { + await expect(cancelTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + }); + + it("Does not revert", async () => { + expect(cancelTx).to.not.reverted; + }); + }); + }); }); diff --git a/test/helpers.ts b/test/helpers.ts index 0e0626ff..5ebf999b 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -208,7 +208,6 @@ export const executeSafeTransaction = async ({ data: transactionData, nonce: await safe.nonce(), }); - console.log("safeIx"); const sigs = await Promise.all(signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx))); @@ -225,8 +224,6 @@ export const executeSafeTransaction = async ({ buildSignatureBytes(sigs) ); - console.log("done?"); - return tx; }; From 868d785c6d3b4e71e08eb748b3ee5ffef1bb0b7d Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 8 Oct 2024 15:42:18 +0100 Subject: [PATCH 046/206] bug fixes --- contracts/DecentSablierStreamManagement.sol | 2 +- test/DecentSablierStreamManagement.test.ts | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index c3157ee8..dfcb9118 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -39,7 +39,7 @@ contract DecentSablierStreamManagement { // Check if the stream is still active if ( !sablier.isCancelable(streamId) || - sablier.getStream(streamId).endTime < block.timestamp + sablier.getStream(streamId).endTime <= block.timestamp ) { return; } diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index b21997ee..28476655 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -371,12 +371,8 @@ describe.only("DecentSablierStreamManagement", () => { await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 120000]); // 2 minutes from now await hre.ethers.provider.send("evm_mine", []); - await MockSablierV2LockupLinear__factory.connect(mockSablierAddress, dao).cancel(streamId); - const stream = await mockSablier.getStream(streamId); - - expect(stream.startTime).to.equal(currentBlockTimestamp); - expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000); + expect(stream.endTime).to.be.greaterThan(currentBlockTimestamp); // The safe cancels the stream await executeSafeTransaction({ @@ -388,8 +384,7 @@ describe.only("DecentSablierStreamManagement", () => { signers: [dao], }); - // advance 1 minute - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 60000]); + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 240000]); // 4 minutes from now await hre.ethers.provider.send("evm_mine", []); cancelTx = await executeSafeTransaction({ From a9b8ba904ca8a3910ad4d5ba5d274c2f84d940b9 Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 8 Oct 2024 18:31:26 +0100 Subject: [PATCH 047/206] Fix tests --- contracts/DecentSablierStreamManagement.sol | 15 ++++++-- contracts/mocks/MockHatsAccount.sol | 11 ++++++ contracts/mocks/MockSablierV2LockupLinear.sol | 8 +++- test/DecentSablierStreamManagement.test.ts | 37 ++++++++++++------- test/helpers.ts | 5 ++- 5 files changed, 54 insertions(+), 22 deletions(-) diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index dfcb9118..e25b302a 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -10,6 +10,7 @@ contract DecentSablierStreamManagement { function withdrawMaxFromStream( ISablierV2LockupLinear sablier, + address recipientHatAccount, uint256 streamId, address to ) public { @@ -21,12 +22,18 @@ contract DecentSablierStreamManagement { // Proxy the Sablier withdrawMax call through IAvatar (Safe) IAvatar(msg.sender).execTransactionFromModule( - address(sablier), + recipientHatAccount, 0, abi.encodeWithSignature( - "withdrawMax(uint256,address)", - streamId, - to + "execute(address,uint256,bytes,uint8)", + address(sablier), + 0, + abi.encodeWithSignature( + "withdrawMax(uint256,address)", + streamId, + to + ), + 0 ), Enum.Operation.Call ); diff --git a/contracts/mocks/MockHatsAccount.sol b/contracts/mocks/MockHatsAccount.sol index 22fd1936..f60fdb0e 100644 --- a/contracts/mocks/MockHatsAccount.sol +++ b/contracts/mocks/MockHatsAccount.sol @@ -22,4 +22,15 @@ contract MockHatsAccount { } return abi.decode(footer, (address)); } + + function execute( + address to, + uint256 value, + bytes calldata data, + uint8 + ) external returns (bytes memory) { + (bool success, bytes memory result) = to.call{value: value}(data); + require(success, "HatsAccount: execution failed"); + return result; + } } diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index ca8e6a52..e67fadd6 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -95,14 +95,17 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { withdrawnAmount = withdrawableAmountOf(streamId); LockupLinear.Stream storage stream = streams[streamId]; - require(to == stream.recipient, "Only recipient can withdraw"); + require( + msg.sender == stream.recipient, + "Only recipient can call withdraw" + ); require( withdrawnAmount <= withdrawableAmountOf(streamId), "Insufficient withdrawable amount" ); stream.totalAmount -= withdrawnAmount; - IERC20(stream.asset).transfer(stream.recipient, withdrawnAmount); + IERC20(stream.asset).transfer(to, withdrawnAmount); } function cancel(uint256 streamId) external { @@ -113,6 +116,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { uint128 withdrawableAmount = withdrawableAmountOf(streamId); uint128 refundAmount = stream.totalAmount - withdrawableAmount; + // TODO: instead of deleting, update state similar to how the real Sablier contract does delete streams[streamId]; if (withdrawableAmount > 0) { diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 28476655..97757089 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -27,7 +27,7 @@ import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from "./GlobalSafeDeployments.test"; -describe.only("DecentSablierStreamManagement", () => { +describe("DecentSablierStreamManagement", () => { let dao: SignerWithAddress; let gnosisSafe: GnosisSafeL2; @@ -59,6 +59,7 @@ describe.only("DecentSablierStreamManagement", () => { let enableModuleTx: ethers.ContractTransactionResponse; let createAndDeclareTreeWithRolesAndStreamsTx: ethers.ContractTransactionResponse; + const streamFundsMax = ethers.parseEther("100"); beforeEach(async () => { const signers = await hre.ethers.getSigners(); @@ -157,7 +158,7 @@ describe.only("DecentSablierStreamManagement", () => { { sablier: mockSablierAddress, sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), + totalAmount: streamFundsMax, asset: mockERC20Address, cancelable: true, transferable: false, @@ -210,19 +211,20 @@ describe.only("DecentSablierStreamManagement", () => { describe("When the stream has funds", () => { beforeEach(async () => { - // No action has been taken yet on the stream. Balance should be untouched. - expect(await mockSablier.withdrawableAmountOf(streamId)).to.not.eq(0); - // Advance time to the end of the stream await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000]); await hre.ethers.provider.send("evm_mine", []); + // No action has been taken yet on the stream. Balance should be untouched. + expect(await mockSablier.withdrawableAmountOf(streamId)).to.eq(streamFundsMax); + const recipientHatAccount = await getHatAccount( 2n, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, - decentHatsAddress + decentHatsAddress, + dao ); withdrawTx = await executeSafeTransaction({ @@ -230,13 +232,12 @@ describe.only("DecentSablierStreamManagement", () => { to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( "withdrawMaxFromStream", - [mockSablierAddress, streamId, await recipientHatAccount.getAddress()] + [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address] ), signers: [dao], }); - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2692000]); - await hre.ethers.provider.send("evm_mine", []); + expect(withdrawTx).to.not.reverted; }); it("Emits an ExecutionSuccess event", async () => { @@ -265,14 +266,21 @@ describe.only("DecentSablierStreamManagement", () => { erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, - decentHatsAddress + decentHatsAddress, + dao ); // The recipient withdraws the full amount - await MockSablierV2LockupLinear__factory.connect(mockSablierAddress, dao).withdrawMax( - streamId, - await recipientHatAccount.getAddress() + await recipientHatAccount.execute( + mockSablierAddress, + 0n, + MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData("withdrawMax", [ + streamId, + dao.address, + ]), + 0 ); + expect(await mockSablier.withdrawableAmountOf(streamId)).to.equal(0); withdrawTx = await executeSafeTransaction({ @@ -280,7 +288,7 @@ describe.only("DecentSablierStreamManagement", () => { to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( "withdrawMaxFromStream", - [mockSablierAddress, streamId, await recipientHatAccount.getAddress()] + [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address] ), signers: [dao], }); @@ -331,6 +339,7 @@ describe.only("DecentSablierStreamManagement", () => { }); it("Cancels the stream", async () => { + // TODO: use stream.statusOf instead expect((await mockSablier.getStream(streamId)).cancelable).to.equal(false); }); }); diff --git a/test/helpers.ts b/test/helpers.ts index 5ebf999b..6c8b1a9a 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -232,7 +232,8 @@ export const getHatAccount = async ( erc6551RegistryImplementation: ERC6551Registry, mockHatsAccountImplementationAddress: string, mockHatsAddress: string, - decentHatsAddress: string + decentHatsAddress: string, + signer: ethers.Signer ) => { const salt = solidityPackedKeccak256( ["string", "uint256", "address"], @@ -247,7 +248,7 @@ export const getHatAccount = async ( hatId ); - const hatAccount = MockHatsAccount__factory.connect(hatAccountAddress, hre.ethers.provider); + const hatAccount = MockHatsAccount__factory.connect(hatAccountAddress, signer); return hatAccount; }; From fac23781829cad66762c6cb168bd554c0d2124e2 Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 8 Oct 2024 19:18:42 +0100 Subject: [PATCH 048/206] Cleanup, use more accurate code in sablier mock --- contracts/DecentSablierStreamManagement.sol | 8 +++--- .../interfaces/sablier/ISablierV2Lockup.sol | 4 +++ contracts/interfaces/sablier/LockupLinear.sol | 27 ++++++++++++++----- contracts/mocks/MockSablierV2LockupLinear.sol | 26 ++++++++++++++++-- test/DecentSablierStreamManagement.test.ts | 3 +-- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index e25b302a..1444dad8 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -4,6 +4,7 @@ pragma solidity =0.8.19; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; +import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; contract DecentSablierStreamManagement { string public constant NAME = "DecentSablierStreamManagement"; @@ -43,10 +44,11 @@ contract DecentSablierStreamManagement { ISablierV2LockupLinear sablier, uint256 streamId ) public { - // Check if the stream is still active + // Check if the stream can be cancelled + LockupLinear.Status streamStatus = sablier.statusOf(streamId); if ( - !sablier.isCancelable(streamId) || - sablier.getStream(streamId).endTime <= block.timestamp + streamStatus != LockupLinear.Status.PENDING && + streamStatus != LockupLinear.Status.STREAMING ) { return; } diff --git a/contracts/interfaces/sablier/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol index 5a55c512..98c3e706 100644 --- a/contracts/interfaces/sablier/ISablierV2Lockup.sol +++ b/contracts/interfaces/sablier/ISablierV2Lockup.sol @@ -19,4 +19,8 @@ interface ISablierV2Lockup { ) external view returns (LockupLinear.Stream memory); function cancel(uint256 streamId) external; + + function statusOf( + uint256 streamId + ) external view returns (LockupLinear.Status status); } diff --git a/contracts/interfaces/sablier/LockupLinear.sol b/contracts/interfaces/sablier/LockupLinear.sol index 3b7eb887..97df9877 100644 --- a/contracts/interfaces/sablier/LockupLinear.sol +++ b/contracts/interfaces/sablier/LockupLinear.sol @@ -28,13 +28,28 @@ library LockupLinear { struct Stream { address sender; - address recipient; - uint128 totalAmount; - address asset; - bool cancelable; - bool transferable; uint40 startTime; - uint40 cliffTime; uint40 endTime; + uint40 cliffTime; + bool cancelable; + bool wasCanceled; + address asset; + bool transferable; + uint128 totalAmount; + address recipient; + } + + /// @notice Enum representing the different statuses of a stream. + /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. + /// @custom:value1 STREAMING Active stream where assets are currently being streamed. + /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. + /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. + /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. + enum Status { + PENDING, + STREAMING, + SETTLED, + CANCELED, + DEPLETED } } diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index e67fadd6..174c4beb 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -42,6 +42,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { totalAmount: params.totalAmount, asset: address(params.asset), cancelable: params.cancelable, + wasCanceled: false, transferable: params.transferable, startTime: params.timestamps.start, cliffTime: params.timestamps.cliff, @@ -116,8 +117,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { uint128 withdrawableAmount = withdrawableAmountOf(streamId); uint128 refundAmount = stream.totalAmount - withdrawableAmount; - // TODO: instead of deleting, update state similar to how the real Sablier contract does - delete streams[streamId]; + streams[streamId].wasCanceled = true; if (withdrawableAmount > 0) { IERC20(stream.asset).transfer(stream.recipient, withdrawableAmount); @@ -130,4 +130,26 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { function isCancelable(uint256 streamId) external view returns (bool) { return streams[streamId].cancelable; } + + /// @dev Retrieves the stream's status without performing a null check. + function statusOf( + uint256 streamId + ) public view returns (LockupLinear.Status) { + uint256 withdrawableAmount = withdrawableAmountOf(streamId); + if (withdrawableAmount == 0) { + return LockupLinear.Status.DEPLETED; + } else if (streams[streamId].wasCanceled) { + return LockupLinear.Status.CANCELED; + } + + if (block.timestamp < streams[streamId].startTime) { + return LockupLinear.Status.PENDING; + } + + if (block.timestamp < streams[streamId].endTime) { + return LockupLinear.Status.STREAMING; + } else { + return LockupLinear.Status.SETTLED; + } + } } diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 97757089..60ad02d0 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -339,8 +339,7 @@ describe("DecentSablierStreamManagement", () => { }); it("Cancels the stream", async () => { - // TODO: use stream.statusOf instead - expect((await mockSablier.getStream(streamId)).cancelable).to.equal(false); + expect(await mockSablier.statusOf(streamId)).to.equal(3); // 3 === LockupLinear.Status.CANCELED }); }); From 2f5bd7a51857a91ca50c8653f17129463fad8cec Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 8 Oct 2024 14:33:22 -0400 Subject: [PATCH 049/206] Autoformat typescript files --- test/DecentHats_0_1_0.test.ts | 468 ++++++++++++--------- test/DecentSablierStreamManagement.test.ts | 303 ++++++++----- test/helpers.ts | 67 ++- 3 files changed, 516 insertions(+), 322 deletions(-) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index f0da3930..0d42dc8e 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -22,7 +22,10 @@ import { expect } from "chai"; import { ethers, solidityPackedKeccak256 } from "ethers"; import hre from "hardhat"; -import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test"; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, +} from "./GlobalSafeDeployments.test"; import { buildSafeTransaction, buildSignatureBytes, @@ -64,27 +67,34 @@ describe("DecentHats_0_1_0", () => { mockHatsAddress = await mockHats.getAddress(); keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); - mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); + mockHatsAccountImplementation = await new MockHatsAccount__factory( + deployer + ).deploy(); + mockHatsAccountImplementationAddress = + await mockHatsAccountImplementation.getAddress(); decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); decentHatsAddress = await decentHats.getAddress(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [dao.address], - 1, - hre.ethers.ZeroAddress, - hre.ethers.ZeroHash, - hre.ethers.ZeroAddress, - hre.ethers.ZeroAddress, - 0, - hre.ethers.ZeroAddress, - ]); - - const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`); + const gnosisSafeL2SingletonAddress = + await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = + GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + [dao.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ]); + + const saltNum = BigInt( + `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` + ); const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, @@ -94,15 +104,27 @@ describe("DecentHats_0_1_0", () => { ); gnosisSafeAddress = predictedGnosisSafeAddress; - await gnosisSafeProxyFactory.createProxyWithNonce(gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, saltNum); + await gnosisSafeProxyFactory.createProxyWithNonce( + gnosisSafeL2SingletonAddress, + createGnosisSetupCalldata, + saltNum + ); - gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); + gnosisSafe = GnosisSafeL2__factory.connect( + predictedGnosisSafeAddress, + deployer + ); // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockSablier = await new MockSablierV2LockupLinear__factory( + deployer + ).deploy(); mockSablierAddress = await mockSablier.getAddress(); - mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK"); + mockERC20 = await new MockERC20__factory(deployer).deploy( + "MockERC20", + "MCK" + ); mockERC20Address = await mockERC20.getAddress(); await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); @@ -115,9 +137,11 @@ describe("DecentHats_0_1_0", () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData("enableModule", [ - decentHatsAddress, - ]), + transactionData: + GnosisSafeL2__factory.createInterface().encodeFunctionData( + "enableModule", + [decentHatsAddress] + ), signers: [dao], }); }); @@ -128,7 +152,9 @@ describe("DecentHats_0_1_0", () => { }); it("Emits an EnabledModule event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentHatsAddress); + await expect(enableModuleTx) + .to.emit(gnosisSafe, "EnabledModule") + .withArgs(decentHatsAddress); }); }); @@ -139,48 +165,56 @@ describe("DecentHats_0_1_0", () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ + transactionData: + DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: + mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + ], }, - ], - }, - ]), + ] + ), signers: [dao], }); }); it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess"); + await expect(createAndDeclareTreeTx).to.emit( + gnosisSafe, + "ExecutionSuccess" + ); }); it("Emits an ExecutionFromModuleSuccess event", async () => { @@ -202,31 +236,39 @@ describe("DecentHats_0_1_0", () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], - }, - ]), + transactionData: + DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: + mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [], + }, + ] + ), signers: [dao], }); }); it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, "ExecutionSuccess"); + await expect(createAndDeclareTreeTx2).to.emit( + gnosisSafe, + "ExecutionSuccess" + ); }); it("Emits an ExecutionFromModuleSuccess event", async () => { @@ -261,7 +303,10 @@ describe("DecentHats_0_1_0", () => { hatId ); - const hatAccount = MockHatsAccount__factory.connect(hatAccountAddress, hre.ethers.provider); + const hatAccount = MockHatsAccount__factory.connect( + hatAccountAddress, + hre.ethers.provider + ); return hatAccount; }; @@ -272,7 +317,9 @@ describe("DecentHats_0_1_0", () => { for (let i = 0n; i < currentCount; i++) { const topHatAccount = await getHatAccount(i); expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); + expect(await topHatAccount.tokenImplementation()).eq( + mockHatsAddress + ); } }); }); @@ -283,68 +330,77 @@ describe("DecentHats_0_1_0", () => { let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! + .timestamp; createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ + transactionData: + DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: + mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], }, ], }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ]), + ] + ), signers: [dao], }); }); it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess"); + await expect(createAndDeclareTreeTx).to.emit( + gnosisSafe, + "ExecutionSuccess" + ); }); it("Emits an ExecutionFromModuleSuccess event", async () => { @@ -360,7 +416,9 @@ describe("DecentHats_0_1_0", () => { }); it("Creates a Sablier stream for the hat with stream parameters", async () => { - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); expect(streamCreatedEvents.length).to.equal(1); const event = streamCreatedEvents[0]; @@ -370,12 +428,16 @@ describe("DecentHats_0_1_0", () => { }); it("Does not create a Sablier stream for hats without stream parameters", async () => { - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created }); it("Creates a Sablier stream with correct timestamps", async () => { - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); expect(streamCreatedEvents.length).to.equal(1); const streamId = streamCreatedEvents[0].args.streamId; @@ -390,74 +452,82 @@ describe("DecentHats_0_1_0", () => { let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! + .timestamp; await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ + transactionData: + DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: + mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("50"), - asset: mockERC20Address, - cancelable: false, - transferable: true, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, // No cliff - end: currentBlockTimestamp + 1296000, // 15 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("50"), + asset: mockERC20Address, + cancelable: false, + transferable: true, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, // No cliff + end: currentBlockTimestamp + 1296000, // 15 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], }, ], }, - ], - }, - ]), + ] + ), signers: [dao], }); }); it("Creates multiple Sablier streams for a single hat", async () => { - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); expect(streamCreatedEvents.length).to.equal(2); const event1 = streamCreatedEvents[0]; @@ -472,27 +542,39 @@ describe("DecentHats_0_1_0", () => { }); it("Creates streams with correct parameters", async () => { - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); - const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); + const stream1 = await mockSablier.getStream( + streamCreatedEvents[0].args.streamId + ); expect(stream1.cancelable).to.be.true; expect(stream1.transferable).to.be.false; expect(stream1.endTime - stream1.startTime).to.equal(2592000); - const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); + const stream2 = await mockSablier.getStream( + streamCreatedEvents[1].args.streamId + ); expect(stream2.cancelable).to.be.false; expect(stream2.transferable).to.be.true; expect(stream2.endTime - stream2.startTime).to.equal(1296000); }); it("Creates streams with correct timestamps", async () => { - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); - const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); + const stream1 = await mockSablier.getStream( + streamCreatedEvents[0].args.streamId + ); expect(stream1.startTime).to.equal(currentBlockTimestamp); expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); - const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); + const stream2 = await mockSablier.getStream( + streamCreatedEvents[1].args.streamId + ); expect(stream2.startTime).to.equal(currentBlockTimestamp); expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); }); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 60ad02d0..8e1b0ea5 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -23,9 +23,16 @@ import { expect } from "chai"; import { ethers } from "ethers"; import hre from "hardhat"; -import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from "./helpers"; +import { + executeSafeTransaction, + getHatAccount, + predictGnosisSafeAddress, +} from "./helpers"; -import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from "./GlobalSafeDeployments.test"; +import { + getGnosisSafeProxyFactory, + getGnosisSafeL2Singleton, +} from "./GlobalSafeDeployments.test"; describe("DecentSablierStreamManagement", () => { let dao: SignerWithAddress; @@ -66,31 +73,40 @@ describe("DecentSablierStreamManagement", () => { const [deployer] = signers; [, dao] = signers; - decentSablierManagement = await new DecentSablierStreamManagement__factory(deployer).deploy(); + decentSablierManagement = await new DecentSablierStreamManagement__factory( + deployer + ).deploy(); decentSablierManagementAddress = await decentSablierManagement.getAddress(); - mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); - mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); + mockHatsAccountImplementation = await new MockHatsAccount__factory( + deployer + ).deploy(); + mockHatsAccountImplementationAddress = + await mockHatsAccountImplementation.getAddress(); decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); decentHatsAddress = await decentHats.getAddress(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [dao.address], - 1, - hre.ethers.ZeroAddress, - hre.ethers.ZeroHash, - hre.ethers.ZeroAddress, - hre.ethers.ZeroAddress, - 0, - hre.ethers.ZeroAddress, - ]); - - const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`); + const gnosisSafeL2SingletonAddress = + await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = + GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + [dao.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ]); + + const saltNum = BigInt( + `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` + ); const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, @@ -100,15 +116,27 @@ describe("DecentSablierStreamManagement", () => { ); gnosisSafeAddress = predictedGnosisSafeAddress; - await gnosisSafeProxyFactory.createProxyWithNonce(gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, saltNum); + await gnosisSafeProxyFactory.createProxyWithNonce( + gnosisSafeL2SingletonAddress, + createGnosisSetupCalldata, + saltNum + ); - gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); + gnosisSafe = GnosisSafeL2__factory.connect( + predictedGnosisSafeAddress, + deployer + ); // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockSablier = await new MockSablierV2LockupLinear__factory( + deployer + ).deploy(); mockSablierAddress = await mockSablier.getAddress(); - mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK"); + mockERC20 = await new MockERC20__factory(deployer).deploy( + "MockERC20", + "MCK" + ); mockERC20Address = await mockERC20.getAddress(); await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); @@ -117,11 +145,16 @@ describe("DecentSablierStreamManagement", () => { await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData("enableModule", [decentHatsAddress]), + transactionData: + GnosisSafeL2__factory.createInterface().encodeFunctionData( + "enableModule", + [decentHatsAddress] + ), signers: [dao], }); - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! + .timestamp; mockHats = await new MockHats__factory(deployer).deploy(); mockHatsAddress = await mockHats.getAddress(); @@ -131,56 +164,68 @@ describe("DecentSablierStreamManagement", () => { createAndDeclareTreeWithRolesAndStreamsTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData("createAndDeclareTree", [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ + transactionData: + DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: dao.address, - sablierParams: [ + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: streamFundsMax, - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: dao.address, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: streamFundsMax, + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], }, ], }, - ], - }, - ]), + ] + ), signers: [dao], }); - await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit(gnosisSafe, "ExecutionSuccess"); - await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit( + gnosisSafe, + "ExecutionSuccess" + ); + await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit( + gnosisSafe, + "ExecutionFromModuleSuccess" + ); - const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated() + ); expect(streamCreatedEvents.length).to.equal(1); streamId = streamCreatedEvents[0].args.streamId; @@ -189,9 +234,11 @@ describe("DecentSablierStreamManagement", () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData("enableModule", [ - decentSablierManagementAddress, - ]), + transactionData: + GnosisSafeL2__factory.createInterface().encodeFunctionData( + "enableModule", + [decentSablierManagementAddress] + ), signers: [dao], }); }); @@ -202,7 +249,9 @@ describe("DecentSablierStreamManagement", () => { }); it("Emits an EnabledModule event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentSablierManagementAddress); + await expect(enableModuleTx) + .to.emit(gnosisSafe, "EnabledModule") + .withArgs(decentSablierManagementAddress); }); }); @@ -212,11 +261,15 @@ describe("DecentSablierStreamManagement", () => { describe("When the stream has funds", () => { beforeEach(async () => { // Advance time to the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000]); + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + currentBlockTimestamp + 2592000, + ]); await hre.ethers.provider.send("evm_mine", []); // No action has been taken yet on the stream. Balance should be untouched. - expect(await mockSablier.withdrawableAmountOf(streamId)).to.eq(streamFundsMax); + expect(await mockSablier.withdrawableAmountOf(streamId)).to.eq( + streamFundsMax + ); const recipientHatAccount = await getHatAccount( 2n, @@ -230,10 +283,16 @@ describe("DecentSablierStreamManagement", () => { withdrawTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, - transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "withdrawMaxFromStream", - [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address] - ), + transactionData: + DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "withdrawMaxFromStream", + [ + mockSablierAddress, + await recipientHatAccount.getAddress(), + streamId, + dao.address, + ] + ), signers: [dao], }); @@ -258,7 +317,9 @@ describe("DecentSablierStreamManagement", () => { describe("When the stream has no funds", () => { beforeEach(async () => { // Advance time to the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000]); + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + currentBlockTimestamp + 2592000, + ]); await hre.ethers.provider.send("evm_mine", []); const recipientHatAccount = await getHatAccount( @@ -274,10 +335,10 @@ describe("DecentSablierStreamManagement", () => { await recipientHatAccount.execute( mockSablierAddress, 0n, - MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData("withdrawMax", [ - streamId, - dao.address, - ]), + MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData( + "withdrawMax", + [streamId, dao.address] + ), 0 ); @@ -286,10 +347,16 @@ describe("DecentSablierStreamManagement", () => { withdrawTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, - transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "withdrawMaxFromStream", - [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address] - ), + transactionData: + DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "withdrawMaxFromStream", + [ + mockSablierAddress, + await recipientHatAccount.getAddress(), + streamId, + dao.address, + ] + ), signers: [dao], }); }); @@ -299,7 +366,10 @@ describe("DecentSablierStreamManagement", () => { }); it("Does not emit an ExecutionFromModuleSuccess event", async () => { - await expect(withdrawTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + await expect(withdrawTx).to.not.emit( + gnosisSafe, + "ExecutionFromModuleSuccess" + ); }); it("Does not revert", async () => { @@ -314,16 +384,19 @@ describe("DecentSablierStreamManagement", () => { describe("When the stream is active", () => { beforeEach(async () => { // Advance time to before the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 60000]); // 1 minute from now + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + currentBlockTimestamp + 60000, + ]); // 1 minute from now await hre.ethers.provider.send("evm_mine", []); cancelTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, - transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData("cancelStream", [ - mockSablierAddress, - streamId, - ]), + transactionData: + DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "cancelStream", + [mockSablierAddress, streamId] + ), signers: [dao], }); }); @@ -346,16 +419,19 @@ describe("DecentSablierStreamManagement", () => { describe("When the stream has expired", () => { beforeEach(async () => { // Advance time to the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 2592000 + 60000]); // 30 days from now + 1 minute + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + currentBlockTimestamp + 2592000 + 60000, + ]); // 30 days from now + 1 minute await hre.ethers.provider.send("evm_mine", []); cancelTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, - transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData("cancelStream", [ - mockSablierAddress, - streamId, - ]), + transactionData: + DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "cancelStream", + [mockSablierAddress, streamId] + ), signers: [dao], }); }); @@ -365,7 +441,10 @@ describe("DecentSablierStreamManagement", () => { }); it("Does not emit an ExecutionFromModuleSuccess event", async () => { - await expect(cancelTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + await expect(cancelTx).to.not.emit( + gnosisSafe, + "ExecutionFromModuleSuccess" + ); }); it("Does not revert", async () => { @@ -376,7 +455,9 @@ describe("DecentSablierStreamManagement", () => { describe("When the stream has been previously cancelled", () => { beforeEach(async () => { // Advance time to before the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 120000]); // 2 minutes from now + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + currentBlockTimestamp + 120000, + ]); // 2 minutes from now await hre.ethers.provider.send("evm_mine", []); const stream = await mockSablier.getStream(streamId); @@ -386,22 +467,27 @@ describe("DecentSablierStreamManagement", () => { await executeSafeTransaction({ safe: gnosisSafe, to: mockSablierAddress, - transactionData: MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData("cancel", [ - streamId, - ]), + transactionData: + MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData( + "cancel", + [streamId] + ), signers: [dao], }); - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [currentBlockTimestamp + 240000]); // 4 minutes from now + await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + currentBlockTimestamp + 240000, + ]); // 4 minutes from now await hre.ethers.provider.send("evm_mine", []); cancelTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, - transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData("cancelStream", [ - mockSablierAddress, - streamId, - ]), + transactionData: + DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + "cancelStream", + [mockSablierAddress, streamId] + ), signers: [dao], }); }); @@ -411,7 +497,10 @@ describe("DecentSablierStreamManagement", () => { }); it("Does not emit an ExecutionFromModuleSuccess event", async () => { - await expect(cancelTx).to.not.emit(gnosisSafe, "ExecutionFromModuleSuccess"); + await expect(cancelTx).to.not.emit( + gnosisSafe, + "ExecutionFromModuleSuccess" + ); }); it("Does not revert", async () => { diff --git a/test/helpers.ts b/test/helpers.ts index 6c8b1a9a..c4a538f7 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -44,7 +44,10 @@ export const predictGnosisSafeAddress = async ( ["bytes", "uint256"], [ethers.solidityPackedKeccak256(["bytes"], [calldata]), saltNum] ), - ethers.solidityPackedKeccak256(["bytes", "uint256"], [await gnosisFactory.proxyCreationCode(), singleton]) + ethers.solidityPackedKeccak256( + ["bytes", "uint256"], + [await gnosisFactory.proxyCreationCode(), singleton] + ) ); }; @@ -55,14 +58,21 @@ export const calculateProxyAddress = async ( saltNonce: string ): Promise => { const masterCopyAddress = masterCopy.toLowerCase().replace(/^0x/, ""); - const byteCode = "0x602d8060093d393df3363d3d373d3d3d363d73" + masterCopyAddress + "5af43d82803e903d91602b57fd5bf3"; + const byteCode = + "0x602d8060093d393df3363d3d373d3d3d363d73" + + masterCopyAddress + + "5af43d82803e903d91602b57fd5bf3"; const salt = ethers.solidityPackedKeccak256( ["bytes32", "uint256"], [ethers.solidityPackedKeccak256(["bytes"], [initData]), saltNonce] ); - return ethers.getCreate2Address(await factory.getAddress(), salt, ethers.keccak256(byteCode)); + return ethers.getCreate2Address( + await factory.getAddress(), + salt, + ethers.keccak256(byteCode) + ); }; export const safeSignTypedData = async ( @@ -100,7 +110,9 @@ export const safeSignTypedData = async ( }; export const buildSignatureBytes = (signatures: SafeSignature[]): string => { - signatures.sort((left, right) => left.signer.toLowerCase().localeCompare(right.signer.toLowerCase())); + signatures.sort((left, right) => + left.signer.toLowerCase().localeCompare(right.signer.toLowerCase()) + ); let signatureBytes = "0x"; for (const sig of signatures) { signatureBytes += sig.data.slice(2); @@ -172,25 +184,31 @@ export const encodeMultiSend = (txs: MetaTransaction[]): string => { ); }; -export const mockTransaction = async (): Promise => { - return { - to: await getMockContract().getAddress(), - value: 0n, - // eslint-disable-next-line camelcase - data: MockContract__factory.createInterface().encodeFunctionData("doSomething"), - operation: 0, +export const mockTransaction = + async (): Promise => { + return { + to: await getMockContract().getAddress(), + value: 0n, + // eslint-disable-next-line camelcase + data: MockContract__factory.createInterface().encodeFunctionData( + "doSomething" + ), + operation: 0, + }; }; -}; -export const mockRevertTransaction = async (): Promise => { - return { - to: await getMockContract().getAddress(), - value: 0n, - // eslint-disable-next-line camelcase - data: MockContract__factory.createInterface().encodeFunctionData("revertSomething"), - operation: 0, +export const mockRevertTransaction = + async (): Promise => { + return { + to: await getMockContract().getAddress(), + value: 0n, + // eslint-disable-next-line camelcase + data: MockContract__factory.createInterface().encodeFunctionData( + "revertSomething" + ), + operation: 0, + }; }; -}; export const executeSafeTransaction = async ({ safe, @@ -209,7 +227,9 @@ export const executeSafeTransaction = async ({ nonce: await safe.nonce(), }); - const sigs = await Promise.all(signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx))); + const sigs = await Promise.all( + signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx)) + ); const tx = await safe.execTransaction( safeTx.to, @@ -248,7 +268,10 @@ export const getHatAccount = async ( hatId ); - const hatAccount = MockHatsAccount__factory.connect(hatAccountAddress, signer); + const hatAccount = MockHatsAccount__factory.connect( + hatAccountAddress, + signer + ); return hatAccount; }; From bf80360d78bc941f6c2dc7f36413ae2005bb9828 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:32:39 -0400 Subject: [PATCH 050/206] use ModuleProxyFactory to deploy AutoAdmin --- contracts/DecentAutonomousAdmin.sol | 8 +-- contracts/DecentHats_0_2_0.sol | 51 +++++++++---------- .../core/019_deploy_DecentAutonomousAdmin.ts | 9 ++++ 3 files changed, 36 insertions(+), 32 deletions(-) create mode 100644 deploy/core/019_deploy_DecentAutonomousAdmin.ts diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index ce23043a..fd7b7cb4 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -8,8 +8,6 @@ contract DecentAutonomousAdmin { string public constant NAME = "DecentAutonomousAdmin"; string public version_ = "0.1.0"; - uint256 public adminHatId; - struct SablierStreamInfo { uint256 streamId; ISablierV2LockupLinear sablierV2LockupLinear; @@ -23,11 +21,9 @@ contract DecentAutonomousAdmin { } // ////////////////////////////////////////////////////////////// - // Constructor + // initializer // ////////////////////////////////////////////////////////////// - constructor(uint256 _adminHatId) { - adminHatId = _adminHatId; - } + function setUp() public {} // ////////////////////////////////////////////////////////////// // Public Functions diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index 7286aa80..58681c53 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -12,6 +12,8 @@ import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; +import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; +import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; contract DecentHats_0_2_0 { string public constant NAME = "DecentHats_0_2_0"; @@ -47,6 +49,8 @@ contract DecentHats_0_2_0 { IHats hatsProtocol; IERC6551Registry registry; IHatsModuleFactory hatsModuleFactory; + ModuleProxyFactory moduleProxyFactory; + address decentAutonomousAdminMasterCopy; address hatsAccountImplementation; address keyValuePairs; address hatsElectionEligibilityImplementation; @@ -75,11 +79,13 @@ contract DecentHats_0_2_0 { (uint256 adminHatId, ) = _createAdminHatAndAccount( params.hatsProtocol, - topHatId, - params.adminHat, - topHatAccount, params.registry, + params.moduleProxyFactory, + params.decentAutonomousAdminMasterCopy, params.hatsAccountImplementation, + topHatAccount, + topHatId, + params.adminHat, salt ); @@ -138,10 +144,12 @@ contract DecentHats_0_2_0 { address _keyValuePairs, uint256 topHatId ) internal { - string[] memory keys = new string[](1); - string[] memory values = new string[](1); + string[] memory keys = new string[](2); + string[] memory values = new string[](2); keys[0] = "topHatId"; values[0] = Strings.toString(topHatId); + keys[1] = "decentHatsAddress"; + values[1] = Strings.toHexString(address(this)); IAvatar(msg.sender).execTransactionFromModule( _keyValuePairs, @@ -281,11 +289,13 @@ contract DecentHats_0_2_0 { function _createAdminHatAndAccount( IHats hatsProtocol, - uint256 topHatId, - Hat calldata hat, - address topHatAccount, IERC6551Registry registry, + ModuleProxyFactory moduleProxyFactory, + address decentAutonomousAdminMasterCopy, address hatsAccountImplementation, + address topHatAccount, + uint256 topHatId, + Hat calldata hat, bytes32 salt ) internal returns (uint256 adminHatId, address accountAddress) { adminHatId = _createHat(hatsProtocol, topHatId, hat, topHatAccount); @@ -297,26 +307,15 @@ contract DecentHats_0_2_0 { address(hatsProtocol), adminHatId ); - address adminInstance = _deployDecentAutonomousAdmin(salt, topHatId); - hatsProtocol.mintHat(adminHatId, adminInstance); - } - - function _deployDecentAutonomousAdmin( - bytes32 salt, - uint256 _adminHatId - ) internal returns (address deployedAddress) { - bytes memory creationCode = _getCreationCode(_adminHatId); - assembly { - deployedAddress := create2( - 0, - add(creationCode, 0x20), - mload(creationCode), - salt + hatsProtocol.mintHat( + adminHatId, + moduleProxyFactory.deployModule( + decentAutonomousAdminMasterCopy, + abi.encodeWithSignature("setUp()"), + uint256(keccak256(abi.encodePacked(salt, adminHatId))) ) - } - - require(deployedAddress != address(0), "CREATE2: Failed on deploy"); + ); } function _getCreationCode( diff --git a/deploy/core/019_deploy_DecentAutonomousAdmin.ts b/deploy/core/019_deploy_DecentAutonomousAdmin.ts new file mode 100644 index 00000000..f1adb696 --- /dev/null +++ b/deploy/core/019_deploy_DecentAutonomousAdmin.ts @@ -0,0 +1,9 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + await deployNonUpgradeable(hre, "DecentAutonomousAdmin"); +}; + +export default func; From 216e1e018845065d424449c3a1b56500b9855765 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:32:51 -0400 Subject: [PATCH 051/206] update tests to support changes --- test/DecentAutonomousAdmin.test.ts | 2 +- test/DecentHats_0_2_0.test.ts | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index 62082fbb..c9d9093f 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -49,7 +49,7 @@ describe("DecentAutonomousAdminHat", function () { const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0] // Deploy DecentAutonomousAdminHat contract with the admin hat ID - adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy(adminHatId) + adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy() const adminHatAddress = await adminHat.getAddress() // Mint the admin hat to adminHatWearer await hatsProtocol.mintHat(adminHatId, adminHatAddress) diff --git a/test/DecentHats_0_2_0.test.ts b/test/DecentHats_0_2_0.test.ts index fb530edb..e12d2f9e 100644 --- a/test/DecentHats_0_2_0.test.ts +++ b/test/DecentHats_0_2_0.test.ts @@ -17,6 +17,10 @@ import { MockERC20, MockHatsModuleFactory__factory, MockHatsElectionEligibility__factory, + ModuleProxyFactory__factory, + ModuleProxyFactory, + DecentAutonomousAdmin__factory, + DecentAutonomousAdmin, } from "../typechain-types" import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" @@ -96,6 +100,9 @@ describe("DecentHats_0_2_0", () => { let mockHatsElectionEligibilityImplementationAddress: string let mockHatsModuleFactoryAddress: string + let moduleProxyFactory: ModuleProxyFactory + let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin + beforeEach(async () => { const signers = await hre.ethers.getSigners() const [deployer] = signers @@ -116,6 +123,9 @@ describe("DecentHats_0_2_0", () => { decentHats = await new DecentHats_0_2_0__factory(deployer).deploy() decentHatsAddress = await decentHats.getAddress() + moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy() + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory() const gnosisSafeL2Singleton = getGnosisSafeL2Singleton() const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress() @@ -202,6 +212,8 @@ describe("DecentHats_0_2_0", () => { keyValuePairs: await keyValuePairs.getAddress(), topHatDetails: "", topHatImageURI: "", + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, details: "", @@ -292,6 +304,8 @@ describe("DecentHats_0_2_0", () => { keyValuePairs: await keyValuePairs.getAddress(), topHatDetails: "", topHatImageURI: "", + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, details: "", @@ -394,6 +408,8 @@ describe("DecentHats_0_2_0", () => { keyValuePairs: await keyValuePairs.getAddress(), topHatDetails: "", topHatImageURI: "", + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, details: "", @@ -534,6 +550,8 @@ describe("DecentHats_0_2_0", () => { keyValuePairs: await keyValuePairs.getAddress(), topHatDetails: "", topHatImageURI: "", + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, details: "", From 1524e94ca47c9588974f916346c4704fc4962b6e Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 9 Oct 2024 16:08:42 +0100 Subject: [PATCH 052/206] Separate new and/or mock structs from existing and/or production code --- contracts/DecentSablierStreamManagement.sol | 17 +++--- .../interfaces/sablier/ISablierV2Lockup.sol | 6 +- .../sablier/ISablierV2LockupLinear.sol | 3 +- contracts/interfaces/sablier/LockupLinear.sol | 27 --------- .../interfaces/sablier/LockupLinear2.sol | 31 +++++++++++ contracts/mocks/MockLockupLinear.sol | 55 +++++++++++++++++++ contracts/mocks/MockSablierV2LockupLinear.sol | 35 ++++++------ 7 files changed, 115 insertions(+), 59 deletions(-) create mode 100644 contracts/interfaces/sablier/LockupLinear2.sol create mode 100644 contracts/mocks/MockLockupLinear.sol diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index 1444dad8..24f44142 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -3,14 +3,14 @@ pragma solidity =0.8.19; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; -import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; +import {ISablierV2Lockup} from "./interfaces/sablier/ISablierV2Lockup.sol"; +import {LockupLinear2} from "./interfaces/sablier/LockupLinear2.sol"; contract DecentSablierStreamManagement { string public constant NAME = "DecentSablierStreamManagement"; function withdrawMaxFromStream( - ISablierV2LockupLinear sablier, + ISablierV2Lockup sablier, address recipientHatAccount, uint256 streamId, address to @@ -40,15 +40,12 @@ contract DecentSablierStreamManagement { ); } - function cancelStream( - ISablierV2LockupLinear sablier, - uint256 streamId - ) public { + function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public { // Check if the stream can be cancelled - LockupLinear.Status streamStatus = sablier.statusOf(streamId); + LockupLinear2.Status streamStatus = sablier.statusOf(streamId); if ( - streamStatus != LockupLinear.Status.PENDING && - streamStatus != LockupLinear.Status.STREAMING + streamStatus != LockupLinear2.Status.PENDING && + streamStatus != LockupLinear2.Status.STREAMING ) { return; } diff --git a/contracts/interfaces/sablier/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol index 98c3e706..cce723e0 100644 --- a/contracts/interfaces/sablier/ISablierV2Lockup.sol +++ b/contracts/interfaces/sablier/ISablierV2Lockup.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {LockupLinear} from "../sablier/LockupLinear.sol"; +import {LockupLinear2} from "../sablier/LockupLinear2.sol"; interface ISablierV2Lockup { function withdrawableAmountOf( @@ -16,11 +16,11 @@ interface ISablierV2Lockup { function getStream( uint256 streamId - ) external view returns (LockupLinear.Stream memory); + ) external view returns (LockupLinear2.Stream memory); function cancel(uint256 streamId) external; function statusOf( uint256 streamId - ) external view returns (LockupLinear.Status status); + ) external view returns (LockupLinear2.Status status); } diff --git a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol index ebcc6d50..0aa6cac9 100644 --- a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol +++ b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol @@ -2,10 +2,9 @@ pragma solidity ^0.8.0; import {LockupLinear} from "./LockupLinear.sol"; -import {ISablierV2Lockup} from "./ISablierV2Lockup.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -interface ISablierV2LockupLinear is ISablierV2Lockup { +interface ISablierV2LockupLinear { function createWithTimestamps( LockupLinear.CreateWithTimestamps calldata params ) external returns (uint256 streamId); diff --git a/contracts/interfaces/sablier/LockupLinear.sol b/contracts/interfaces/sablier/LockupLinear.sol index 97df9877..0225d060 100644 --- a/contracts/interfaces/sablier/LockupLinear.sol +++ b/contracts/interfaces/sablier/LockupLinear.sol @@ -25,31 +25,4 @@ library LockupLinear { address account; uint256 fee; } - - struct Stream { - address sender; - uint40 startTime; - uint40 endTime; - uint40 cliffTime; - bool cancelable; - bool wasCanceled; - address asset; - bool transferable; - uint128 totalAmount; - address recipient; - } - - /// @notice Enum representing the different statuses of a stream. - /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. - /// @custom:value1 STREAMING Active stream where assets are currently being streamed. - /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. - /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. - /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. - enum Status { - PENDING, - STREAMING, - SETTLED, - CANCELED, - DEPLETED - } } diff --git a/contracts/interfaces/sablier/LockupLinear2.sol b/contracts/interfaces/sablier/LockupLinear2.sol new file mode 100644 index 00000000..2507cfb2 --- /dev/null +++ b/contracts/interfaces/sablier/LockupLinear2.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +library LockupLinear2 { + struct Stream { + address sender; + uint40 startTime; + uint40 endTime; + uint40 cliffTime; + bool cancelable; + bool wasCanceled; + address asset; + bool transferable; + uint128 totalAmount; + address recipient; + } + + /// @notice Enum representing the different statuses of a stream. + /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. + /// @custom:value1 STREAMING Active stream where assets are currently being streamed. + /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. + /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. + /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. + enum Status { + PENDING, + STREAMING, + SETTLED, + CANCELED, + DEPLETED + } +} diff --git a/contracts/mocks/MockLockupLinear.sol b/contracts/mocks/MockLockupLinear.sol new file mode 100644 index 00000000..911d220b --- /dev/null +++ b/contracts/mocks/MockLockupLinear.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +library MockLockupLinear { + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + Timestamps timestamps; + Broker broker; + } + + struct Timestamps { + uint40 start; + uint40 cliff; + uint40 end; + } + + struct Broker { + address account; + uint256 fee; + } + + struct Stream { + address sender; + uint40 startTime; + uint40 endTime; + uint40 cliffTime; + bool cancelable; + bool wasCanceled; + address asset; + bool transferable; + uint128 totalAmount; + address recipient; + } + + /// @notice Enum representing the different statuses of a stream. + /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. + /// @custom:value1 STREAMING Active stream where assets are currently being streamed. + /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. + /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. + /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. + enum Status { + PENDING, + STREAMING, + SETTLED, + CANCELED, + DEPLETED + } +} diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 174c4beb..9926a994 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -2,11 +2,12 @@ pragma solidity =0.8.19; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "../interfaces/sablier/ISablierV2LockupLinear.sol"; -import {LockupLinear} from "../interfaces/sablier/LockupLinear.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ISablierV2LockupLinear} from "../interfaces/sablier/ISablierV2LockupLinear.sol"; +import {MockLockupLinear} from "./MockLockupLinear.sol"; -contract MockSablierV2LockupLinear is ISablierV2LockupLinear { - mapping(uint256 => LockupLinear.Stream) public streams; +contract MockSablierV2LockupLinear { + mapping(uint256 => MockLockupLinear.Stream) public streams; uint256 public nextStreamId = 1; // Add this event declaration at the contract level @@ -24,8 +25,8 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { ); function createWithTimestamps( - LockupLinear.CreateWithTimestamps calldata params - ) external override returns (uint256 streamId) { + MockLockupLinear.CreateWithTimestamps calldata params + ) external returns (uint256 streamId) { require( params.asset.transferFrom( msg.sender, @@ -36,7 +37,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { ); streamId = nextStreamId++; - streams[streamId] = LockupLinear.Stream({ + streams[streamId] = MockLockupLinear.Stream({ sender: params.sender, recipient: params.recipient, totalAmount: params.totalAmount, @@ -68,14 +69,14 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { function getStream( uint256 streamId - ) external view returns (LockupLinear.Stream memory) { + ) external view returns (MockLockupLinear.Stream memory) { return streams[streamId]; } function withdrawableAmountOf( uint256 streamId ) public view returns (uint128) { - LockupLinear.Stream memory stream = streams[streamId]; + MockLockupLinear.Stream memory stream = streams[streamId]; if (block.timestamp <= stream.startTime) { return 0; } @@ -94,7 +95,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { address to ) external returns (uint128 withdrawnAmount) { withdrawnAmount = withdrawableAmountOf(streamId); - LockupLinear.Stream storage stream = streams[streamId]; + MockLockupLinear.Stream storage stream = streams[streamId]; require( msg.sender == stream.recipient, @@ -110,7 +111,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { } function cancel(uint256 streamId) external { - LockupLinear.Stream memory stream = streams[streamId]; + MockLockupLinear.Stream memory stream = streams[streamId]; require(stream.cancelable, "Stream is not cancelable"); require(msg.sender == stream.sender, "Only sender can cancel"); @@ -134,22 +135,22 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { /// @dev Retrieves the stream's status without performing a null check. function statusOf( uint256 streamId - ) public view returns (LockupLinear.Status) { + ) public view returns (MockLockupLinear.Status) { uint256 withdrawableAmount = withdrawableAmountOf(streamId); if (withdrawableAmount == 0) { - return LockupLinear.Status.DEPLETED; + return MockLockupLinear.Status.DEPLETED; } else if (streams[streamId].wasCanceled) { - return LockupLinear.Status.CANCELED; + return MockLockupLinear.Status.CANCELED; } if (block.timestamp < streams[streamId].startTime) { - return LockupLinear.Status.PENDING; + return MockLockupLinear.Status.PENDING; } if (block.timestamp < streams[streamId].endTime) { - return LockupLinear.Status.STREAMING; + return MockLockupLinear.Status.STREAMING; } else { - return LockupLinear.Status.SETTLED; + return MockLockupLinear.Status.SETTLED; } } } From a1e23c469773b30b012fa5427fa063c3cd2c42c4 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 12:21:03 -0400 Subject: [PATCH 053/206] Add PRBMath to package, for Sablier interfaces --- package-lock.json | 7 +++++++ package.json | 1 + 2 files changed, 8 insertions(+) diff --git a/package-lock.json b/package-lock.json index 2f51a13f..8b4f73ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0", + "@prb/math": "^4.0.3", "dotenv": "^16.4.5", "hardhat": "^2.22.2", "hardhat-dependency-compiler": "^1.1.4", @@ -1811,6 +1812,12 @@ "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==", "dev": true }, + "node_modules/@prb/math": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@prb/math/-/math-4.0.3.tgz", + "integrity": "sha512-/RSt3VU1k2m3ox6U6kUL1MrktnAHr8vhydXu4eDtqFAms1gm3XnGpoZIPaK1lm2zdJQmKBwJ4EXALPARsuOlaA==", + "dev": true + }, "node_modules/@scure/base": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", diff --git a/package.json b/package.json index d6620d11..de81f04e 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0", + "@prb/math": "^4.0.3", "dotenv": "^16.4.5", "hardhat": "^2.22.2", "hardhat-dependency-compiler": "^1.1.4", From 1ec965046b262037f437088c9ab44690b0c19509 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 12:23:14 -0400 Subject: [PATCH 054/206] Added minimum amount of "full" Sablier interfaces needed for DecentSablierStreamManagement, to also be future-proof --- .../interfaces/sablier/full/IAdminable.sol | 41 ++ .../interfaces/sablier/full/IERC4096.sol | 20 + .../sablier/full/ISablierV2Lockup.sol | 395 ++++++++++++++++++ .../sablier/full/ISablierV2NFTDescriptor.sol | 19 + .../sablier/full/types/DataTypes.sol | 374 +++++++++++++++++ 5 files changed, 849 insertions(+) create mode 100644 contracts/interfaces/sablier/full/IAdminable.sol create mode 100644 contracts/interfaces/sablier/full/IERC4096.sol create mode 100644 contracts/interfaces/sablier/full/ISablierV2Lockup.sol create mode 100644 contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol create mode 100644 contracts/interfaces/sablier/full/types/DataTypes.sol diff --git a/contracts/interfaces/sablier/full/IAdminable.sol b/contracts/interfaces/sablier/full/IAdminable.sol new file mode 100644 index 00000000..e5ee0956 --- /dev/null +++ b/contracts/interfaces/sablier/full/IAdminable.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +/// @title IAdminable +/// @notice Contract module that provides a basic access control mechanism, with an admin that can be +/// granted exclusive access to specific functions. The inheriting contract must set the initial admin +/// in the constructor. +interface IAdminable { + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Emitted when the admin is transferred. + /// @param oldAdmin The address of the old admin. + /// @param newAdmin The address of the new admin. + event TransferAdmin(address indexed oldAdmin, address indexed newAdmin); + + /*////////////////////////////////////////////////////////////////////////// + CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice The address of the admin account or contract. + function admin() external view returns (address); + + /*////////////////////////////////////////////////////////////////////////// + NON-CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Transfers the contract admin to a new address. + /// + /// @dev Notes: + /// - Does not revert if the admin is the same. + /// - This function can potentially leave the contract without an admin, thereby removing any + /// functionality that is only available to the admin. + /// + /// Requirements: + /// - `msg.sender` must be the contract admin. + /// + /// @param newAdmin The address of the new admin. + function transferAdmin(address newAdmin) external; +} diff --git a/contracts/interfaces/sablier/full/IERC4096.sol b/contracts/interfaces/sablier/full/IERC4096.sol new file mode 100644 index 00000000..29bcc6ea --- /dev/null +++ b/contracts/interfaces/sablier/full/IERC4096.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol) + +pragma solidity ^0.8.19; + +import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; +import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; + +/// @title ERC-721 Metadata Update Extension +interface IERC4906 is IERC165, IERC721 { + /// @dev This event emits when the metadata of a token is changed. + /// So that the third-party platforms such as NFT market could + /// timely update the images and related attributes of the NFT. + event MetadataUpdate(uint256 _tokenId); + + /// @dev This event emits when the metadata of a range of tokens is changed. + /// So that the third-party platforms such as NFT market could + /// timely update the images and related attributes of the NFTs. + event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); +} diff --git a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol new file mode 100644 index 00000000..8e5b21e3 --- /dev/null +++ b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +import {IERC4906} from "./IERC4096.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import {UD60x18} from "@prb/math/src/UD60x18.sol"; + +import {Lockup} from "./types/DataTypes.sol"; +import {IAdminable} from "./IAdminable.sol"; +import {ISablierV2NFTDescriptor} from "./ISablierV2NFTDescriptor.sol"; + +/// @title ISablierV2Lockup +/// @notice Common logic between all Sablier V2 Lockup contracts. +interface ISablierV2Lockup is + IAdminable, // 0 inherited components + IERC4906, // 2 inherited components + IERC721Metadata // 2 inherited components +{ + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier. + /// @param admin The address of the current contract admin. + /// @param recipient The address of the recipient contract put on the allowlist. + event AllowToHook(address indexed admin, address recipient); + + /// @notice Emitted when a stream is canceled. + /// @param streamId The ID of the stream. + /// @param sender The address of the stream's sender. + /// @param recipient The address of the stream's recipient. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's + /// decimals. + /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the + /// asset's decimals. + event CancelLockupStream( + uint256 streamId, + address indexed sender, + address indexed recipient, + IERC20 indexed asset, + uint128 senderAmount, + uint128 recipientAmount + ); + + /// @notice Emitted when a sender gives up the right to cancel a stream. + /// @param streamId The ID of the stream. + event RenounceLockupStream(uint256 indexed streamId); + + /// @notice Emitted when the admin sets a new NFT descriptor contract. + /// @param admin The address of the current contract admin. + /// @param oldNFTDescriptor The address of the old NFT descriptor contract. + /// @param newNFTDescriptor The address of the new NFT descriptor contract. + event SetNFTDescriptor( + address indexed admin, + ISablierV2NFTDescriptor oldNFTDescriptor, + ISablierV2NFTDescriptor newNFTDescriptor + ); + + /// @notice Emitted when assets are withdrawn from a stream. + /// @param streamId The ID of the stream. + /// @param to The address that has received the withdrawn assets. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals. + event WithdrawFromLockupStream( + uint256 indexed streamId, + address indexed to, + IERC20 indexed asset, + uint128 amount + ); + + /*////////////////////////////////////////////////////////////////////////// + CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Retrieves the address of the ERC-20 asset to be distributed. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getAsset(uint256 streamId) external view returns (IERC20 asset); + + /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getDepositedAmount( + uint256 streamId + ) external view returns (uint128 depositedAmount); + + /// @notice Retrieves the stream's end time, which is a Unix timestamp. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getEndTime( + uint256 streamId + ) external view returns (uint40 endTime); + + /// @notice Retrieves the stream's recipient. + /// @dev Reverts if the NFT has been burned. + /// @param streamId The stream ID for the query. + function getRecipient( + uint256 streamId + ) external view returns (address recipient); + + /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's + /// decimals. This amount is always zero unless the stream was canceled. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getRefundedAmount( + uint256 streamId + ) external view returns (uint128 refundedAmount); + + /// @notice Retrieves the stream's sender. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getSender(uint256 streamId) external view returns (address sender); + + /// @notice Retrieves the stream's start time, which is a Unix timestamp. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getStartTime( + uint256 streamId + ) external view returns (uint40 startTime); + + /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getWithdrawnAmount( + uint256 streamId + ) external view returns (uint128 withdrawnAmount); + + /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier + /// when a stream is canceled or when assets are withdrawn. + /// @dev See {ISablierLockupRecipient} for more information. + function isAllowedToHook( + address recipient + ) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this + /// flag is always `false`. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isCancelable(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isCold(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream is depleted. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isDepleted(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream exists. + /// @dev Does not revert if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isStream(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream NFT can be transferred. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isTransferable( + uint256 streamId + ) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isWarm(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point + /// number where 1e18 is 100%. + /// @dev This value is hard coded as a constant. + function MAX_BROKER_FEE() external view returns (UD60x18); + + /// @notice Counter for stream IDs, used in the create functions. + function nextStreamId() external view returns (uint256); + + /// @notice Contract that generates the non-fungible token URI. + function nftDescriptor() external view returns (ISablierV2NFTDescriptor); + + /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units + /// of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function refundableAmountOf( + uint256 streamId + ) external view returns (uint128 refundableAmount); + + /// @notice Retrieves the stream's status. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function statusOf( + uint256 streamId + ) external view returns (Lockup.Status status); + + /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// + /// Notes: + /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited + /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent + /// to the total amount withdrawn. + /// + /// @param streamId The stream ID for the query. + function streamedAmountOf( + uint256 streamId + ) external view returns (uint128 streamedAmount); + + /// @notice Retrieves a flag indicating whether the stream was canceled. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function wasCanceled(uint256 streamId) external view returns (bool result); + + /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's + /// decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function withdrawableAmountOf( + uint256 streamId + ) external view returns (uint128 withdrawableAmount); + + /*////////////////////////////////////////////////////////////////////////// + NON-CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn. + /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts. + /// + /// @dev Emits an {AllowToHook} event. + /// + /// Notes: + /// - Does not revert if the contract is already on the allowlist. + /// - This is an irreversible operation. The contract cannot be removed from the allowlist. + /// + /// Requirements: + /// - `msg.sender` must be the contract admin. + /// - `recipient` must have a non-zero code size. + /// - `recipient` must implement {ISablierLockupRecipient}. + /// + /// @param recipient The address of the contract to allow for hooks. + function allowToHook(address recipient) external; + + /// @notice Burns the NFT associated with the stream. + /// + /// @dev Emits a {Transfer} event. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `streamId` must reference a depleted stream. + /// - The NFT must exist. + /// - `msg.sender` must be either the NFT owner or an approved third party. + /// + /// @param streamId The ID of the stream NFT to burn. + function burn(uint256 streamId) external; + + /// @notice Cancels the stream and refunds any remaining assets to the sender. + /// + /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the + /// stream is marked as depleted. + /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract. + /// + /// Requirements: + /// - Must not be delegate called. + /// - The stream must be warm and cancelable. + /// - `msg.sender` must be the stream's sender. + /// + /// @param streamId The ID of the stream to cancel. + function cancel(uint256 streamId) external; + + /// @notice Cancels multiple streams and refunds any remaining assets to the sender. + /// + /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events. + /// + /// Notes: + /// - Refer to the notes in {cancel}. + /// + /// Requirements: + /// - All requirements from {cancel} must be met for each stream. + /// + /// @param streamIds The IDs of the streams to cancel. + function cancelMultiple(uint256[] calldata streamIds) external; + + /// @notice Removes the right of the stream's sender to cancel the stream. + /// + /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event. + /// + /// Notes: + /// - This is an irreversible operation. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `streamId` must reference a warm stream. + /// - `msg.sender` must be the stream's sender. + /// - The stream must be cancelable. + /// + /// @param streamId The ID of the stream to renounce. + function renounce(uint256 streamId) external; + + /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs. + /// + /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event. + /// + /// Notes: + /// - Does not revert if the NFT descriptor is the same. + /// + /// Requirements: + /// - `msg.sender` must be the contract admin. + /// + /// @param newNFTDescriptor The address of the new NFT descriptor contract. + function setNFTDescriptor( + ISablierV2NFTDescriptor newNFTDescriptor + ) external; + + /// @notice Withdraws the provided amount of assets from the stream to the `to` address. + /// + /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `streamId` must not reference a null or depleted stream. + /// - `to` must not be the zero address. + /// - `amount` must be greater than zero and must not exceed the withdrawable amount. + /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party. + /// + /// @param streamId The ID of the stream to withdraw from. + /// @param to The address receiving the withdrawn assets. + /// @param amount The amount to withdraw, denoted in units of the asset's decimals. + function withdraw(uint256 streamId, address to, uint128 amount) external; + + /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`. + /// + /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - Refer to the notes in {withdraw}. + /// + /// Requirements: + /// - Refer to the requirements in {withdraw}. + /// + /// @param streamId The ID of the stream to withdraw from. + /// @param to The address receiving the withdrawn assets. + /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals. + function withdrawMax( + uint256 streamId, + address to + ) external returns (uint128 withdrawnAmount); + + /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the + /// NFT to `newRecipient`. + /// + /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event. + /// + /// Notes: + /// - If the withdrawable amount is zero, the withdrawal is skipped. + /// - Refer to the notes in {withdraw}. + /// + /// Requirements: + /// - `msg.sender` must be the stream's recipient. + /// - Refer to the requirements in {withdraw}. + /// - Refer to the requirements in {IERC721.transferFrom}. + /// + /// @param streamId The ID of the stream NFT to transfer. + /// @param newRecipient The address of the new owner of the stream NFT. + /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals. + function withdrawMaxAndTransfer( + uint256 streamId, + address newRecipient + ) external returns (uint128 withdrawnAmount); + + /// @notice Withdraws assets from streams to the recipient of each stream. + /// + /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events. + /// + /// Notes: + /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient. + /// + /// Requirements: + /// - Must not be delegate called. + /// - There must be an equal number of `streamIds` and `amounts`. + /// - Each stream ID in the array must not reference a null or depleted stream. + /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount. + /// + /// @param streamIds The IDs of the streams to withdraw from. + /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals. + function withdrawMultiple( + uint256[] calldata streamIds, + uint128[] calldata amounts + ) external; +} diff --git a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol new file mode 100644 index 00000000..49fec926 --- /dev/null +++ b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; + +/// @title ISablierV2NFTDescriptor +/// @notice This contract generates the URI describing the Sablier V2 stream NFTs. +/// @dev Inspired by Uniswap V3 Positions NFTs. +interface ISablierV2NFTDescriptor { + /// @notice Produces the URI describing a particular stream NFT. + /// @dev This is a data URI with the JSON contents directly inlined. + /// @param sablier The address of the Sablier contract the stream was created in. + /// @param streamId The ID of the stream for which to produce a description. + /// @return uri The URI of the ERC721-compliant metadata. + function tokenURI( + IERC721Metadata sablier, + uint256 streamId + ) external view returns (string memory uri); +} diff --git a/contracts/interfaces/sablier/full/types/DataTypes.sol b/contracts/interfaces/sablier/full/types/DataTypes.sol new file mode 100644 index 00000000..b7b50c59 --- /dev/null +++ b/contracts/interfaces/sablier/full/types/DataTypes.sol @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {UD2x18} from "@prb/math/src/UD2x18.sol"; +import {UD60x18} from "@prb/math/src/UD60x18.sol"; + +// DataTypes.sol +// +// This file defines all structs used in V2 Core, most of which are organized under three namespaces: +// +// - Lockup +// - LockupDynamic +// - LockupLinear +// - LockupTranched +// +// You will notice that some structs contain "slot" annotations - they are used to indicate the +// storage layout of the struct. It is more gas efficient to group small data types together so +// that they fit in a single 32-byte slot. + +/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero. +/// @param account The address receiving the broker's fee. +/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%. +struct Broker { + address account; + UD60x18 fee; +} + +/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}. +library Lockup { + /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's + /// decimals. + /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot + /// saves gas. + /// @param deposited The initial amount deposited in the stream, net of broker fee. + /// @param withdrawn The cumulative amount withdrawn from the stream. + /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero. + struct Amounts { + // slot 0 + uint128 deposited; + uint128 withdrawn; + // slot 1 + uint128 refunded; + } + + /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the + /// asset's decimals. + /// @param deposit The amount to deposit in the stream. + /// @param brokerFee The broker fee amount. + struct CreateAmounts { + uint128 deposit; + uint128 brokerFee; + } + + /// @notice Enum representing the different statuses of a stream. + /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. + /// @custom:value1 STREAMING Active stream where assets are currently being streamed. + /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. + /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. + /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. + enum Status { + PENDING, + STREAMING, + SETTLED, + CANCELED, + DEPLETED + } + + /// @notice A common data structure to be stored in all {SablierV2Lockup} models. + /// @dev The fields are arranged like this to save gas via tight variable packing. + /// @param sender The address distributing the assets, with the ability to cancel the stream. + /// @param startTime The Unix timestamp indicating the stream's start. + /// @param endTime The Unix timestamp indicating the stream's end. + /// @param isCancelable Boolean indicating if the stream is cancelable. + /// @param wasCanceled Boolean indicating if the stream was canceled. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param isDepleted Boolean indicating if the stream is depleted. + /// @param isStream Boolean indicating if the struct entity exists. + /// @param isTransferable Boolean indicating if the stream NFT is transferable. + /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the + /// asset's decimals. + struct Stream { + // slot 0 + address sender; + uint40 startTime; + uint40 endTime; + bool isCancelable; + bool wasCanceled; + // slot 1 + IERC20 asset; + bool isDepleted; + bool isStream; + bool isTransferable; + // slot 2 and 3 + Lockup.Amounts amounts; + } +} + +/// @notice Namespace for the structs used in {SablierV2LockupDynamic}. +library LockupDynamic { + /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are + /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithDurations { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + SegmentWithDuration[] segments; + Broker broker; + } + + /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param startTime The Unix timestamp indicating the stream's start. + /// @param segments Segments used to compose the dynamic distribution function. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + uint40 startTime; + Segment[] segments; + Broker broker; + } + + /// @notice Segment struct used in the Lockup Dynamic stream. + /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals. + /// @param exponent The exponent of the segment, denoted as a fixed-point number. + /// @param timestamp The Unix timestamp indicating the segment's end. + struct Segment { + // slot 0 + uint128 amount; + UD2x18 exponent; + uint40 timestamp; + } + + /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}. + /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals. + /// @param exponent The exponent of the segment, denoted as a fixed-point number. + /// @param duration The time difference in seconds between the segment and the previous one. + struct SegmentWithDuration { + uint128 amount; + UD2x18 exponent; + uint40 duration; + } + + /// @notice Struct encapsulating the full details of a stream. + /// @dev Extends `Lockup.Stream` by including the recipient and the segments. + struct StreamLD { + address sender; + address recipient; + uint40 startTime; + uint40 endTime; + bool isCancelable; + bool wasCanceled; + IERC20 asset; + bool isDepleted; + bool isStream; + bool isTransferable; + Lockup.Amounts amounts; + Segment[] segments; + } + + /// @notice Struct encapsulating the LockupDynamic timestamps. + /// @param start The Unix timestamp indicating the stream's start. + /// @param end The Unix timestamp indicating the stream's end. + struct Timestamps { + uint40 start; + uint40 end; + } +} + +/// @notice Namespace for the structs used in {SablierV2LockupLinear}. +library LockupLinear { + /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithDurations { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + Durations durations; + Broker broker; + } + + /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as + /// Unix timestamps. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + Timestamps timestamps; + Broker broker; + } + + /// @notice Struct encapsulating the cliff duration and the total duration. + /// @param cliff The cliff duration in seconds. + /// @param total The total duration in seconds. + struct Durations { + uint40 cliff; + uint40 total; + } + + /// @notice Struct encapsulating the full details of a stream. + /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time. + struct StreamLL { + address sender; + address recipient; + uint40 startTime; + bool isCancelable; + bool wasCanceled; + IERC20 asset; + uint40 endTime; + bool isDepleted; + bool isStream; + bool isTransferable; + Lockup.Amounts amounts; + uint40 cliffTime; + } + + /// @notice Struct encapsulating the LockupLinear timestamps. + /// @param start The Unix timestamp for the stream's start. + /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff. + /// @param end The Unix timestamp for the stream's end. + struct Timestamps { + uint40 start; + uint40 cliff; + uint40 end; + } +} + +/// @notice Namespace for the structs used in {SablierV2LockupTranched}. +library LockupTranched { + /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are + /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithDurations { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + TrancheWithDuration[] tranches; + Broker broker; + } + + /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param startTime The Unix timestamp indicating the stream's start. + /// @param tranches Tranches used to compose the tranched distribution function. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + uint40 startTime; + Tranche[] tranches; + Broker broker; + } + + /// @notice Struct encapsulating the full details of a stream. + /// @dev Extends `Lockup.Stream` by including the recipient and the tranches. + struct StreamLT { + address sender; + address recipient; + uint40 startTime; + uint40 endTime; + bool isCancelable; + bool wasCanceled; + IERC20 asset; + bool isDepleted; + bool isStream; + bool isTransferable; + Lockup.Amounts amounts; + Tranche[] tranches; + } + + /// @notice Struct encapsulating the LockupTranched timestamps. + /// @param start The Unix timestamp indicating the stream's start. + /// @param end The Unix timestamp indicating the stream's end. + struct Timestamps { + uint40 start; + uint40 end; + } + + /// @notice Tranche struct used in the Lockup Tranched stream. + /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals. + /// @param timestamp The Unix timestamp indicating the tranche's end. + struct Tranche { + // slot 0 + uint128 amount; + uint40 timestamp; + } + + /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}. + /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals. + /// @param duration The time difference in seconds between the tranche and the previous one. + struct TrancheWithDuration { + uint128 amount; + uint40 duration; + } +} From c39571ac6379c136cfb9d24258d6b450d9ceb4f1 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 12:23:58 -0400 Subject: [PATCH 055/206] Use new Sablier interfaces in DecentSablierStreamManagement --- contracts/DecentSablierStreamManagement.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index 24f44142..dcbafe7e 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -3,8 +3,8 @@ pragma solidity =0.8.19; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {ISablierV2Lockup} from "./interfaces/sablier/ISablierV2Lockup.sol"; -import {LockupLinear2} from "./interfaces/sablier/LockupLinear2.sol"; +import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; +import {Lockup} from "./interfaces/sablier/full/types/DataTypes.sol"; contract DecentSablierStreamManagement { string public constant NAME = "DecentSablierStreamManagement"; @@ -42,10 +42,10 @@ contract DecentSablierStreamManagement { function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public { // Check if the stream can be cancelled - LockupLinear2.Status streamStatus = sablier.statusOf(streamId); + Lockup.Status streamStatus = sablier.statusOf(streamId); if ( - streamStatus != LockupLinear2.Status.PENDING && - streamStatus != LockupLinear2.Status.STREAMING + streamStatus != Lockup.Status.PENDING && + streamStatus != Lockup.Status.STREAMING ) { return; } From a4c4141f287ccc08a35ad90b21318843f25f6240 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 12:24:33 -0400 Subject: [PATCH 056/206] Remove newly unused Sablier interfaces --- .../interfaces/sablier/ISablierV2Lockup.sol | 26 ---------------- .../interfaces/sablier/LockupLinear2.sol | 31 ------------------- 2 files changed, 57 deletions(-) delete mode 100644 contracts/interfaces/sablier/ISablierV2Lockup.sol delete mode 100644 contracts/interfaces/sablier/LockupLinear2.sol diff --git a/contracts/interfaces/sablier/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol deleted file mode 100644 index cce723e0..00000000 --- a/contracts/interfaces/sablier/ISablierV2Lockup.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; -import {LockupLinear2} from "../sablier/LockupLinear2.sol"; - -interface ISablierV2Lockup { - function withdrawableAmountOf( - uint256 streamId - ) external view returns (uint128 withdrawableAmount); - - function isCancelable(uint256 streamId) external view returns (bool result); - - function withdrawMax( - uint256 streamId, - address to - ) external returns (uint128 withdrawnAmount); - - function getStream( - uint256 streamId - ) external view returns (LockupLinear2.Stream memory); - - function cancel(uint256 streamId) external; - - function statusOf( - uint256 streamId - ) external view returns (LockupLinear2.Status status); -} diff --git a/contracts/interfaces/sablier/LockupLinear2.sol b/contracts/interfaces/sablier/LockupLinear2.sol deleted file mode 100644 index 2507cfb2..00000000 --- a/contracts/interfaces/sablier/LockupLinear2.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -library LockupLinear2 { - struct Stream { - address sender; - uint40 startTime; - uint40 endTime; - uint40 cliffTime; - bool cancelable; - bool wasCanceled; - address asset; - bool transferable; - uint128 totalAmount; - address recipient; - } - - /// @notice Enum representing the different statuses of a stream. - /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. - /// @custom:value1 STREAMING Active stream where assets are currently being streamed. - /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. - /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. - /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. - enum Status { - PENDING, - STREAMING, - SETTLED, - CANCELED, - DEPLETED - } -} From a3bc214dded4f2d1b9c5d491e8061a644a275159 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:25:01 -0400 Subject: [PATCH 057/206] Downtype "sablier" in SablierStreamParams to an address, and rename it to sablierV2LockupLinear --- contracts/DecentHats_0_2_0.sol | 7 +++---- test/DecentHats_0_2_0.test.ts | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index 58681c53..d24736b0 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -7,7 +7,6 @@ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/IHats.sol"; -import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; @@ -19,7 +18,7 @@ contract DecentHats_0_2_0 { string public constant NAME = "DecentHats_0_2_0"; struct SablierStreamParams { - ISablierV2LockupLinear sablier; + address sablierV2LockupLinear; address sender; address asset; LockupLinear.Timestamps timestamps; @@ -252,7 +251,7 @@ contract DecentHats_0_2_0 { 0, abi.encodeWithSignature( "approve(address,uint256)", - address(sablierParams.sablier), + sablierParams.sablierV2LockupLinear, sablierParams.totalAmount ), Enum.Operation.Call @@ -272,7 +271,7 @@ contract DecentHats_0_2_0 { // Proxy the Sablier call through IAvatar IAvatar(msg.sender).execTransactionFromModule( - address(sablierParams.sablier), + sablierParams.sablierV2LockupLinear, 0, abi.encodeWithSignature( "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", diff --git a/test/DecentHats_0_2_0.test.ts b/test/DecentHats_0_2_0.test.ts index e12d2f9e..0014cc33 100644 --- a/test/DecentHats_0_2_0.test.ts +++ b/test/DecentHats_0_2_0.test.ts @@ -434,7 +434,7 @@ describe("DecentHats_0_2_0", () => { wearer: ethers.ZeroAddress, sablierParams: [ { - sablier: mockSablierAddress, + sablierV2LockupLinear: mockSablierAddress, sender: gnosisSafeAddress, totalAmount: ethers.parseEther("100"), asset: mockERC20Address, @@ -576,7 +576,7 @@ describe("DecentHats_0_2_0", () => { wearer: ethers.ZeroAddress, sablierParams: [ { - sablier: mockSablierAddress, + sablierV2LockupLinear: mockSablierAddress, sender: gnosisSafeAddress, totalAmount: ethers.parseEther("100"), asset: mockERC20Address, @@ -590,7 +590,7 @@ describe("DecentHats_0_2_0", () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, { - sablier: mockSablierAddress, + sablierV2LockupLinear: mockSablierAddress, sender: gnosisSafeAddress, totalAmount: ethers.parseEther("50"), asset: mockERC20Address, From 85543b3494a411bab1a9f1c67748e7052d067195 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 12:21:03 -0400 Subject: [PATCH 058/206] Add PRBMath to package, for Sablier interfaces --- package-lock.json | 7 +++++++ package.json | 1 + 2 files changed, 8 insertions(+) diff --git a/package-lock.json b/package-lock.json index 2f51a13f..8b4f73ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0", + "@prb/math": "^4.0.3", "dotenv": "^16.4.5", "hardhat": "^2.22.2", "hardhat-dependency-compiler": "^1.1.4", @@ -1811,6 +1812,12 @@ "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==", "dev": true }, + "node_modules/@prb/math": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@prb/math/-/math-4.0.3.tgz", + "integrity": "sha512-/RSt3VU1k2m3ox6U6kUL1MrktnAHr8vhydXu4eDtqFAms1gm3XnGpoZIPaK1lm2zdJQmKBwJ4EXALPARsuOlaA==", + "dev": true + }, "node_modules/@scure/base": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", diff --git a/package.json b/package.json index d6620d11..de81f04e 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0", + "@prb/math": "^4.0.3", "dotenv": "^16.4.5", "hardhat": "^2.22.2", "hardhat-dependency-compiler": "^1.1.4", From 42de8fc9b065548ff7d3e85ef04002ba06cfefa8 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 12:23:14 -0400 Subject: [PATCH 059/206] Added minimum amount of "full" Sablier interfaces needed for DecentSablierStreamManagement, to also be future-proof --- .../interfaces/sablier/full/IAdminable.sol | 41 ++ .../interfaces/sablier/full/IERC4096.sol | 20 + .../sablier/full/ISablierV2Lockup.sol | 395 ++++++++++++++++++ .../sablier/full/ISablierV2NFTDescriptor.sol | 19 + .../sablier/full/types/DataTypes.sol | 374 +++++++++++++++++ 5 files changed, 849 insertions(+) create mode 100644 contracts/interfaces/sablier/full/IAdminable.sol create mode 100644 contracts/interfaces/sablier/full/IERC4096.sol create mode 100644 contracts/interfaces/sablier/full/ISablierV2Lockup.sol create mode 100644 contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol create mode 100644 contracts/interfaces/sablier/full/types/DataTypes.sol diff --git a/contracts/interfaces/sablier/full/IAdminable.sol b/contracts/interfaces/sablier/full/IAdminable.sol new file mode 100644 index 00000000..e5ee0956 --- /dev/null +++ b/contracts/interfaces/sablier/full/IAdminable.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +/// @title IAdminable +/// @notice Contract module that provides a basic access control mechanism, with an admin that can be +/// granted exclusive access to specific functions. The inheriting contract must set the initial admin +/// in the constructor. +interface IAdminable { + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Emitted when the admin is transferred. + /// @param oldAdmin The address of the old admin. + /// @param newAdmin The address of the new admin. + event TransferAdmin(address indexed oldAdmin, address indexed newAdmin); + + /*////////////////////////////////////////////////////////////////////////// + CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice The address of the admin account or contract. + function admin() external view returns (address); + + /*////////////////////////////////////////////////////////////////////////// + NON-CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Transfers the contract admin to a new address. + /// + /// @dev Notes: + /// - Does not revert if the admin is the same. + /// - This function can potentially leave the contract without an admin, thereby removing any + /// functionality that is only available to the admin. + /// + /// Requirements: + /// - `msg.sender` must be the contract admin. + /// + /// @param newAdmin The address of the new admin. + function transferAdmin(address newAdmin) external; +} diff --git a/contracts/interfaces/sablier/full/IERC4096.sol b/contracts/interfaces/sablier/full/IERC4096.sol new file mode 100644 index 00000000..29bcc6ea --- /dev/null +++ b/contracts/interfaces/sablier/full/IERC4096.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol) + +pragma solidity ^0.8.19; + +import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; +import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; + +/// @title ERC-721 Metadata Update Extension +interface IERC4906 is IERC165, IERC721 { + /// @dev This event emits when the metadata of a token is changed. + /// So that the third-party platforms such as NFT market could + /// timely update the images and related attributes of the NFT. + event MetadataUpdate(uint256 _tokenId); + + /// @dev This event emits when the metadata of a range of tokens is changed. + /// So that the third-party platforms such as NFT market could + /// timely update the images and related attributes of the NFTs. + event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); +} diff --git a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol new file mode 100644 index 00000000..8e5b21e3 --- /dev/null +++ b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +import {IERC4906} from "./IERC4096.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; +import {UD60x18} from "@prb/math/src/UD60x18.sol"; + +import {Lockup} from "./types/DataTypes.sol"; +import {IAdminable} from "./IAdminable.sol"; +import {ISablierV2NFTDescriptor} from "./ISablierV2NFTDescriptor.sol"; + +/// @title ISablierV2Lockup +/// @notice Common logic between all Sablier V2 Lockup contracts. +interface ISablierV2Lockup is + IAdminable, // 0 inherited components + IERC4906, // 2 inherited components + IERC721Metadata // 2 inherited components +{ + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier. + /// @param admin The address of the current contract admin. + /// @param recipient The address of the recipient contract put on the allowlist. + event AllowToHook(address indexed admin, address recipient); + + /// @notice Emitted when a stream is canceled. + /// @param streamId The ID of the stream. + /// @param sender The address of the stream's sender. + /// @param recipient The address of the stream's recipient. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's + /// decimals. + /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the + /// asset's decimals. + event CancelLockupStream( + uint256 streamId, + address indexed sender, + address indexed recipient, + IERC20 indexed asset, + uint128 senderAmount, + uint128 recipientAmount + ); + + /// @notice Emitted when a sender gives up the right to cancel a stream. + /// @param streamId The ID of the stream. + event RenounceLockupStream(uint256 indexed streamId); + + /// @notice Emitted when the admin sets a new NFT descriptor contract. + /// @param admin The address of the current contract admin. + /// @param oldNFTDescriptor The address of the old NFT descriptor contract. + /// @param newNFTDescriptor The address of the new NFT descriptor contract. + event SetNFTDescriptor( + address indexed admin, + ISablierV2NFTDescriptor oldNFTDescriptor, + ISablierV2NFTDescriptor newNFTDescriptor + ); + + /// @notice Emitted when assets are withdrawn from a stream. + /// @param streamId The ID of the stream. + /// @param to The address that has received the withdrawn assets. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals. + event WithdrawFromLockupStream( + uint256 indexed streamId, + address indexed to, + IERC20 indexed asset, + uint128 amount + ); + + /*////////////////////////////////////////////////////////////////////////// + CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Retrieves the address of the ERC-20 asset to be distributed. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getAsset(uint256 streamId) external view returns (IERC20 asset); + + /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getDepositedAmount( + uint256 streamId + ) external view returns (uint128 depositedAmount); + + /// @notice Retrieves the stream's end time, which is a Unix timestamp. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getEndTime( + uint256 streamId + ) external view returns (uint40 endTime); + + /// @notice Retrieves the stream's recipient. + /// @dev Reverts if the NFT has been burned. + /// @param streamId The stream ID for the query. + function getRecipient( + uint256 streamId + ) external view returns (address recipient); + + /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's + /// decimals. This amount is always zero unless the stream was canceled. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getRefundedAmount( + uint256 streamId + ) external view returns (uint128 refundedAmount); + + /// @notice Retrieves the stream's sender. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getSender(uint256 streamId) external view returns (address sender); + + /// @notice Retrieves the stream's start time, which is a Unix timestamp. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getStartTime( + uint256 streamId + ) external view returns (uint40 startTime); + + /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getWithdrawnAmount( + uint256 streamId + ) external view returns (uint128 withdrawnAmount); + + /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier + /// when a stream is canceled or when assets are withdrawn. + /// @dev See {ISablierLockupRecipient} for more information. + function isAllowedToHook( + address recipient + ) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this + /// flag is always `false`. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isCancelable(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isCold(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream is depleted. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isDepleted(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream exists. + /// @dev Does not revert if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isStream(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream NFT can be transferred. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isTransferable( + uint256 streamId + ) external view returns (bool result); + + /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function isWarm(uint256 streamId) external view returns (bool result); + + /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point + /// number where 1e18 is 100%. + /// @dev This value is hard coded as a constant. + function MAX_BROKER_FEE() external view returns (UD60x18); + + /// @notice Counter for stream IDs, used in the create functions. + function nextStreamId() external view returns (uint256); + + /// @notice Contract that generates the non-fungible token URI. + function nftDescriptor() external view returns (ISablierV2NFTDescriptor); + + /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units + /// of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function refundableAmountOf( + uint256 streamId + ) external view returns (uint128 refundableAmount); + + /// @notice Retrieves the stream's status. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function statusOf( + uint256 streamId + ) external view returns (Lockup.Status status); + + /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals. + /// @dev Reverts if `streamId` references a null stream. + /// + /// Notes: + /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited + /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent + /// to the total amount withdrawn. + /// + /// @param streamId The stream ID for the query. + function streamedAmountOf( + uint256 streamId + ) external view returns (uint128 streamedAmount); + + /// @notice Retrieves a flag indicating whether the stream was canceled. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function wasCanceled(uint256 streamId) external view returns (bool result); + + /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's + /// decimals. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function withdrawableAmountOf( + uint256 streamId + ) external view returns (uint128 withdrawableAmount); + + /*////////////////////////////////////////////////////////////////////////// + NON-CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn. + /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts. + /// + /// @dev Emits an {AllowToHook} event. + /// + /// Notes: + /// - Does not revert if the contract is already on the allowlist. + /// - This is an irreversible operation. The contract cannot be removed from the allowlist. + /// + /// Requirements: + /// - `msg.sender` must be the contract admin. + /// - `recipient` must have a non-zero code size. + /// - `recipient` must implement {ISablierLockupRecipient}. + /// + /// @param recipient The address of the contract to allow for hooks. + function allowToHook(address recipient) external; + + /// @notice Burns the NFT associated with the stream. + /// + /// @dev Emits a {Transfer} event. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `streamId` must reference a depleted stream. + /// - The NFT must exist. + /// - `msg.sender` must be either the NFT owner or an approved third party. + /// + /// @param streamId The ID of the stream NFT to burn. + function burn(uint256 streamId) external; + + /// @notice Cancels the stream and refunds any remaining assets to the sender. + /// + /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the + /// stream is marked as depleted. + /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract. + /// + /// Requirements: + /// - Must not be delegate called. + /// - The stream must be warm and cancelable. + /// - `msg.sender` must be the stream's sender. + /// + /// @param streamId The ID of the stream to cancel. + function cancel(uint256 streamId) external; + + /// @notice Cancels multiple streams and refunds any remaining assets to the sender. + /// + /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events. + /// + /// Notes: + /// - Refer to the notes in {cancel}. + /// + /// Requirements: + /// - All requirements from {cancel} must be met for each stream. + /// + /// @param streamIds The IDs of the streams to cancel. + function cancelMultiple(uint256[] calldata streamIds) external; + + /// @notice Removes the right of the stream's sender to cancel the stream. + /// + /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event. + /// + /// Notes: + /// - This is an irreversible operation. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `streamId` must reference a warm stream. + /// - `msg.sender` must be the stream's sender. + /// - The stream must be cancelable. + /// + /// @param streamId The ID of the stream to renounce. + function renounce(uint256 streamId) external; + + /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs. + /// + /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event. + /// + /// Notes: + /// - Does not revert if the NFT descriptor is the same. + /// + /// Requirements: + /// - `msg.sender` must be the contract admin. + /// + /// @param newNFTDescriptor The address of the new NFT descriptor contract. + function setNFTDescriptor( + ISablierV2NFTDescriptor newNFTDescriptor + ) external; + + /// @notice Withdraws the provided amount of assets from the stream to the `to` address. + /// + /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `streamId` must not reference a null or depleted stream. + /// - `to` must not be the zero address. + /// - `amount` must be greater than zero and must not exceed the withdrawable amount. + /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party. + /// + /// @param streamId The ID of the stream to withdraw from. + /// @param to The address receiving the withdrawn assets. + /// @param amount The amount to withdraw, denoted in units of the asset's decimals. + function withdraw(uint256 streamId, address to, uint128 amount) external; + + /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`. + /// + /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event. + /// + /// Notes: + /// - Refer to the notes in {withdraw}. + /// + /// Requirements: + /// - Refer to the requirements in {withdraw}. + /// + /// @param streamId The ID of the stream to withdraw from. + /// @param to The address receiving the withdrawn assets. + /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals. + function withdrawMax( + uint256 streamId, + address to + ) external returns (uint128 withdrawnAmount); + + /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the + /// NFT to `newRecipient`. + /// + /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event. + /// + /// Notes: + /// - If the withdrawable amount is zero, the withdrawal is skipped. + /// - Refer to the notes in {withdraw}. + /// + /// Requirements: + /// - `msg.sender` must be the stream's recipient. + /// - Refer to the requirements in {withdraw}. + /// - Refer to the requirements in {IERC721.transferFrom}. + /// + /// @param streamId The ID of the stream NFT to transfer. + /// @param newRecipient The address of the new owner of the stream NFT. + /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals. + function withdrawMaxAndTransfer( + uint256 streamId, + address newRecipient + ) external returns (uint128 withdrawnAmount); + + /// @notice Withdraws assets from streams to the recipient of each stream. + /// + /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events. + /// + /// Notes: + /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient. + /// + /// Requirements: + /// - Must not be delegate called. + /// - There must be an equal number of `streamIds` and `amounts`. + /// - Each stream ID in the array must not reference a null or depleted stream. + /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount. + /// + /// @param streamIds The IDs of the streams to withdraw from. + /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals. + function withdrawMultiple( + uint256[] calldata streamIds, + uint128[] calldata amounts + ) external; +} diff --git a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol new file mode 100644 index 00000000..49fec926 --- /dev/null +++ b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; + +/// @title ISablierV2NFTDescriptor +/// @notice This contract generates the URI describing the Sablier V2 stream NFTs. +/// @dev Inspired by Uniswap V3 Positions NFTs. +interface ISablierV2NFTDescriptor { + /// @notice Produces the URI describing a particular stream NFT. + /// @dev This is a data URI with the JSON contents directly inlined. + /// @param sablier The address of the Sablier contract the stream was created in. + /// @param streamId The ID of the stream for which to produce a description. + /// @return uri The URI of the ERC721-compliant metadata. + function tokenURI( + IERC721Metadata sablier, + uint256 streamId + ) external view returns (string memory uri); +} diff --git a/contracts/interfaces/sablier/full/types/DataTypes.sol b/contracts/interfaces/sablier/full/types/DataTypes.sol new file mode 100644 index 00000000..b7b50c59 --- /dev/null +++ b/contracts/interfaces/sablier/full/types/DataTypes.sol @@ -0,0 +1,374 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.19; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {UD2x18} from "@prb/math/src/UD2x18.sol"; +import {UD60x18} from "@prb/math/src/UD60x18.sol"; + +// DataTypes.sol +// +// This file defines all structs used in V2 Core, most of which are organized under three namespaces: +// +// - Lockup +// - LockupDynamic +// - LockupLinear +// - LockupTranched +// +// You will notice that some structs contain "slot" annotations - they are used to indicate the +// storage layout of the struct. It is more gas efficient to group small data types together so +// that they fit in a single 32-byte slot. + +/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero. +/// @param account The address receiving the broker's fee. +/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%. +struct Broker { + address account; + UD60x18 fee; +} + +/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}. +library Lockup { + /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's + /// decimals. + /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot + /// saves gas. + /// @param deposited The initial amount deposited in the stream, net of broker fee. + /// @param withdrawn The cumulative amount withdrawn from the stream. + /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero. + struct Amounts { + // slot 0 + uint128 deposited; + uint128 withdrawn; + // slot 1 + uint128 refunded; + } + + /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the + /// asset's decimals. + /// @param deposit The amount to deposit in the stream. + /// @param brokerFee The broker fee amount. + struct CreateAmounts { + uint128 deposit; + uint128 brokerFee; + } + + /// @notice Enum representing the different statuses of a stream. + /// @custom:value0 PENDING Stream created but not started; assets are in a pending state. + /// @custom:value1 STREAMING Active stream where assets are currently being streamed. + /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them. + /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal. + /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded. + enum Status { + PENDING, + STREAMING, + SETTLED, + CANCELED, + DEPLETED + } + + /// @notice A common data structure to be stored in all {SablierV2Lockup} models. + /// @dev The fields are arranged like this to save gas via tight variable packing. + /// @param sender The address distributing the assets, with the ability to cancel the stream. + /// @param startTime The Unix timestamp indicating the stream's start. + /// @param endTime The Unix timestamp indicating the stream's end. + /// @param isCancelable Boolean indicating if the stream is cancelable. + /// @param wasCanceled Boolean indicating if the stream was canceled. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param isDepleted Boolean indicating if the stream is depleted. + /// @param isStream Boolean indicating if the struct entity exists. + /// @param isTransferable Boolean indicating if the stream NFT is transferable. + /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the + /// asset's decimals. + struct Stream { + // slot 0 + address sender; + uint40 startTime; + uint40 endTime; + bool isCancelable; + bool wasCanceled; + // slot 1 + IERC20 asset; + bool isDepleted; + bool isStream; + bool isTransferable; + // slot 2 and 3 + Lockup.Amounts amounts; + } +} + +/// @notice Namespace for the structs used in {SablierV2LockupDynamic}. +library LockupDynamic { + /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are + /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithDurations { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + SegmentWithDuration[] segments; + Broker broker; + } + + /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param startTime The Unix timestamp indicating the stream's start. + /// @param segments Segments used to compose the dynamic distribution function. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + uint40 startTime; + Segment[] segments; + Broker broker; + } + + /// @notice Segment struct used in the Lockup Dynamic stream. + /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals. + /// @param exponent The exponent of the segment, denoted as a fixed-point number. + /// @param timestamp The Unix timestamp indicating the segment's end. + struct Segment { + // slot 0 + uint128 amount; + UD2x18 exponent; + uint40 timestamp; + } + + /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}. + /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals. + /// @param exponent The exponent of the segment, denoted as a fixed-point number. + /// @param duration The time difference in seconds between the segment and the previous one. + struct SegmentWithDuration { + uint128 amount; + UD2x18 exponent; + uint40 duration; + } + + /// @notice Struct encapsulating the full details of a stream. + /// @dev Extends `Lockup.Stream` by including the recipient and the segments. + struct StreamLD { + address sender; + address recipient; + uint40 startTime; + uint40 endTime; + bool isCancelable; + bool wasCanceled; + IERC20 asset; + bool isDepleted; + bool isStream; + bool isTransferable; + Lockup.Amounts amounts; + Segment[] segments; + } + + /// @notice Struct encapsulating the LockupDynamic timestamps. + /// @param start The Unix timestamp indicating the stream's start. + /// @param end The Unix timestamp indicating the stream's end. + struct Timestamps { + uint40 start; + uint40 end; + } +} + +/// @notice Namespace for the structs used in {SablierV2LockupLinear}. +library LockupLinear { + /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithDurations { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + Durations durations; + Broker broker; + } + + /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as + /// Unix timestamps. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + Timestamps timestamps; + Broker broker; + } + + /// @notice Struct encapsulating the cliff duration and the total duration. + /// @param cliff The cliff duration in seconds. + /// @param total The total duration in seconds. + struct Durations { + uint40 cliff; + uint40 total; + } + + /// @notice Struct encapsulating the full details of a stream. + /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time. + struct StreamLL { + address sender; + address recipient; + uint40 startTime; + bool isCancelable; + bool wasCanceled; + IERC20 asset; + uint40 endTime; + bool isDepleted; + bool isStream; + bool isTransferable; + Lockup.Amounts amounts; + uint40 cliffTime; + } + + /// @notice Struct encapsulating the LockupLinear timestamps. + /// @param start The Unix timestamp for the stream's start. + /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff. + /// @param end The Unix timestamp for the stream's end. + struct Timestamps { + uint40 start; + uint40 cliff; + uint40 end; + } +} + +/// @notice Namespace for the structs used in {SablierV2LockupTranched}. +library LockupTranched { + /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are + /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithDurations { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + TrancheWithDuration[] tranches; + Broker broker; + } + + /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function. + /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be + /// the same as `msg.sender`. + /// @param recipient The address receiving the assets. + /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any + /// broker fee, denoted in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Indicates if the stream is cancelable. + /// @param transferable Indicates if the stream NFT is transferable. + /// @param startTime The Unix timestamp indicating the stream's start. + /// @param tranches Tranches used to compose the tranched distribution function. + /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the + /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero. + struct CreateWithTimestamps { + address sender; + address recipient; + uint128 totalAmount; + IERC20 asset; + bool cancelable; + bool transferable; + uint40 startTime; + Tranche[] tranches; + Broker broker; + } + + /// @notice Struct encapsulating the full details of a stream. + /// @dev Extends `Lockup.Stream` by including the recipient and the tranches. + struct StreamLT { + address sender; + address recipient; + uint40 startTime; + uint40 endTime; + bool isCancelable; + bool wasCanceled; + IERC20 asset; + bool isDepleted; + bool isStream; + bool isTransferable; + Lockup.Amounts amounts; + Tranche[] tranches; + } + + /// @notice Struct encapsulating the LockupTranched timestamps. + /// @param start The Unix timestamp indicating the stream's start. + /// @param end The Unix timestamp indicating the stream's end. + struct Timestamps { + uint40 start; + uint40 end; + } + + /// @notice Tranche struct used in the Lockup Tranched stream. + /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals. + /// @param timestamp The Unix timestamp indicating the tranche's end. + struct Tranche { + // slot 0 + uint128 amount; + uint40 timestamp; + } + + /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}. + /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals. + /// @param duration The time difference in seconds between the tranche and the previous one. + struct TrancheWithDuration { + uint128 amount; + uint40 duration; + } +} From ffc7c0fc4d2fe50823e3d755d5d76b66b530f207 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:50:34 -0400 Subject: [PATCH 060/206] Fix MockSablierV2LockupLinear contract to actually implement full ISablierV2Lockup interface --- contracts/mocks/MockSablierV2LockupLinear.sol | 189 +++++++++++++++++- 1 file changed, 183 insertions(+), 6 deletions(-) diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 8511d364..99ec6c7b 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -1,11 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "../interfaces/sablier/ISablierV2LockupLinear.sol"; -import {LockupLinear} from "../interfaces/sablier/LockupLinear.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {UD60x18} from "@prb/math/src/UD60x18.sol"; +import {ISablierV2NFTDescriptor} from "../interfaces/sablier/full/ISablierV2NFTDescriptor.sol"; +import {ISablierV2Lockup} from "../interfaces/sablier/full/ISablierV2Lockup.sol"; +import {LockupLinear, Lockup} from "../interfaces/sablier/full/types/DataTypes.sol"; -contract MockSablierV2LockupLinear is ISablierV2LockupLinear { +contract MockSablierV2LockupLinear is ISablierV2Lockup { // Define the Stream struct here struct Stream { address sender; @@ -38,7 +40,7 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { function createWithTimestamps( LockupLinear.CreateWithTimestamps calldata params - ) external override returns (uint256 streamId) { + ) external returns (uint256 streamId) { require( params.asset.transferFrom( msg.sender, @@ -167,6 +169,181 @@ contract MockSablierV2LockupLinear is ISablierV2LockupLinear { Stream storage stream = streams[streamId]; stream.totalAmount -= withdrawnAmount; IERC20(stream.asset).transfer(to, withdrawnAmount); - emit WithdrawFromLockupStream(streamId, to, IERC20(stream.asset), withdrawnAmount); + emit WithdrawFromLockupStream( + streamId, + to, + IERC20(stream.asset), + withdrawnAmount + ); } + + function getAsset( + uint256 streamId + ) external view override returns (IERC20) {} + + function getDepositedAmount( + uint256 streamId + ) external view override returns (uint128) {} + + function getEndTime( + uint256 streamId + ) external view override returns (uint40) {} + + function getRecipient( + uint256 streamId + ) external view override returns (address) {} + + function getSender( + uint256 streamId + ) external view override returns (address) {} + + function getStartTime( + uint256 streamId + ) external view override returns (uint40) {} + + function isCancelable( + uint256 streamId + ) external view override returns (bool) {} + + function isTransferable( + uint256 streamId + ) external view override returns (bool) {} + + function refundableAmountOf( + uint256 streamId + ) external view override returns (uint128) {} + + function streamedAmountOf( + uint256 streamId + ) external view override returns (uint128) {} + + function wasCanceled( + uint256 streamId + ) external pure override returns (bool) {} + + function withdrawMultiple( + uint256[] calldata streamIds, + uint128[] calldata amounts + ) external {} + + function withdrawMaxAndTransfer( + uint256 streamId, + address newRecipient + ) external returns (uint128 withdrawnAmount) {} + + function getRefundedAmount( + uint256 streamId + ) external view returns (uint128 refundedAmount) {} + + function getWithdrawnAmount( + uint256 streamId + ) external view returns (uint128 withdrawnAmount) {} + + function isAllowedToHook( + address recipient + ) external view returns (bool result) {} + + function isCold(uint256 streamId) external view returns (bool result) {} + + function isDepleted(uint256 streamId) external view returns (bool result) {} + + function isStream(uint256 streamId) external view returns (bool result) {} + + function isWarm(uint256 streamId) external view returns (bool result) {} + + function getBrokerFee(uint256 streamId) external view returns (uint256) {} + + function getBroker(uint256 streamId) external view returns (address) {} + + function getBrokerFeeBips( + uint256 streamId + ) external view returns (uint256) {} + + function admin() external view override returns (address) {} + + function transferAdmin(address newAdmin) external override {} + + function supportsInterface( + bytes4 interfaceId + ) external view override returns (bool) {} + + function balanceOf( + address owner + ) external view override returns (uint256 balance) {} + + function ownerOf( + uint256 tokenId + ) external view override returns (address owner) {} + + function safeTransferFrom( + address from, + address to, + uint256 tokenId, + bytes calldata data + ) external override {} + + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) external override {} + + function transferFrom( + address from, + address to, + uint256 tokenId + ) external override {} + + function approve(address to, uint256 tokenId) external override {} + + function setApprovalForAll( + address operator, + bool _approved + ) external override {} + + function getApproved( + uint256 tokenId + ) external view override returns (address operator) {} + + function isApprovedForAll( + address owner, + address operator + ) external view override returns (bool) {} + + function name() external view override returns (string memory) {} + + function symbol() external view override returns (string memory) {} + + function tokenURI( + uint256 tokenId + ) external view override returns (string memory) {} + + function MAX_BROKER_FEE() external view override returns (UD60x18) {} + + function nftDescriptor() + external + view + override + returns (ISablierV2NFTDescriptor) + {} + + function statusOf( + uint256 streamId + ) external view override returns (Lockup.Status status) {} + + function allowToHook(address recipient) external override {} + + function burn(uint256 streamId) external override {} + + function cancelMultiple(uint256[] calldata streamIds) external override {} + + function setNFTDescriptor( + ISablierV2NFTDescriptor newNFTDescriptor + ) external override {} + + function withdraw( + uint256 streamId, + address to, + uint128 amount + ) external override {} } From 60fb6d86b16ca1c838ce14af19cfcba39e2e5fba Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:51:28 -0400 Subject: [PATCH 061/206] Use new "full" Sablier interfaces in DecenHats_0_2_0 --- contracts/DecentHats_0_2_0.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index d24736b0..4a78de51 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -7,7 +7,7 @@ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/IHats.sol"; -import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; +import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; @@ -22,7 +22,7 @@ contract DecentHats_0_2_0 { address sender; address asset; LockupLinear.Timestamps timestamps; - LockupLinear.Broker broker; + Broker broker; uint128 totalAmount; bool cancelable; bool transferable; From fabf38daad1a7f8e38ef7120f1b98cbc311d09cd Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:52:52 -0400 Subject: [PATCH 062/206] Type the sablier address as the "full" ISablierV2Lockup type in DecentAutonomousAdmin --- contracts/DecentAutonomousAdmin.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index fd7b7cb4..191470e6 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -2,7 +2,7 @@ pragma solidity =0.8.19; import "./interfaces/hats/IHats.sol"; import "./interfaces/hats/IHatsElectionEligibility.sol"; -import "./interfaces/sablier/ISablierV2LockupLinear.sol"; +import "./interfaces/sablier/full/ISablierV2Lockup.sol"; contract DecentAutonomousAdmin { string public constant NAME = "DecentAutonomousAdmin"; @@ -10,7 +10,7 @@ contract DecentAutonomousAdmin { struct SablierStreamInfo { uint256 streamId; - ISablierV2LockupLinear sablierV2LockupLinear; + ISablierV2Lockup sablierV2Lockup; } struct TriggerStartArgs { address currentWearer; @@ -80,7 +80,7 @@ contract DecentAutonomousAdmin { address withdrawTo ) internal { for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { - _sablierStreamInfo[i].sablierV2LockupLinear.withdrawMax( + _sablierStreamInfo[i].sablierV2Lockup.withdrawMax( _sablierStreamInfo[i].streamId, withdrawTo ); @@ -99,7 +99,7 @@ contract DecentAutonomousAdmin { for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { uint128 withdrawableAmount = _sablierStreamInfo[i] - .sablierV2LockupLinear + .sablierV2Lockup .withdrawableAmountOf(_sablierStreamInfo[i].streamId); if (withdrawableAmount > 0) { @@ -115,7 +115,7 @@ contract DecentAutonomousAdmin { for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { uint128 withdrawableAmount = _sablierStreamInfo[i] - .sablierV2LockupLinear + .sablierV2Lockup .withdrawableAmountOf(_sablierStreamInfo[i].streamId); if (withdrawableAmount > 0) { From 38f80ef50032de593e44d7f38852a8d696dfe7f4 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:53:23 -0400 Subject: [PATCH 063/206] Remove changes from original ISablierV2LockupLinear interface, so no bytecode changes to DecentHats_0_1_0 occur --- .../sablier/ISablierV2LockupLinear.sol | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol index 4bf0c724..0aa6cac9 100644 --- a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol +++ b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol @@ -8,35 +8,4 @@ interface ISablierV2LockupLinear { function createWithTimestamps( LockupLinear.CreateWithTimestamps calldata params ) external returns (uint256 streamId); - - /// @notice Emitted when assets are withdrawn from a stream. - /// @param streamId The ID of the stream. - /// @param to The address that has received the withdrawn assets. - /// @param asset The contract address of the ERC-20 asset to be distributed. - /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals. - event WithdrawFromLockupStream(uint256 indexed streamId, address indexed to, IERC20 indexed asset, uint128 amount); - - /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`. - /// - /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event. - /// - /// Notes: - /// - Refer to the notes in {withdraw}. - /// - /// Requirements: - /// - Refer to the requirements in {withdraw}. - /// - /// @param streamId The ID of the stream to withdraw from. - /// @param to The address receiving the withdrawn assets. - /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals. - function withdrawMax( - uint256 streamId, - address to - ) external returns (uint128 withdrawnAmount); - - /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's - /// decimals. - /// @dev Reverts if `streamId` references a null stream. - /// @param streamId The stream ID for the query. - function withdrawableAmountOf(uint256 streamId) external view returns (uint128 withdrawableAmount); } From 1470b4ed014cc2f1d04251954978703fcc20dd9c Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:54:34 -0400 Subject: [PATCH 064/206] Named imports in DecentAutonomousAdmin --- contracts/DecentAutonomousAdmin.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 191470e6..21915faa 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -import "./interfaces/hats/IHats.sol"; -import "./interfaces/hats/IHatsElectionEligibility.sol"; -import "./interfaces/sablier/full/ISablierV2Lockup.sol"; +import {IHats} from "./interfaces/hats/IHats.sol"; +import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; +import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; contract DecentAutonomousAdmin { string public constant NAME = "DecentAutonomousAdmin"; From 43fad8e9418c9b13087063a0fd12c6778dc592b0 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 14:57:25 -0400 Subject: [PATCH 065/206] Copy in the FULL Hats interfaces --- contracts/interfaces/hats/full/HatsErrors.sol | 86 ++++++++ contracts/interfaces/hats/full/HatsEvents.sol | 92 ++++++++ contracts/interfaces/hats/full/IHats.sol | 205 ++++++++++++++++++ .../interfaces/hats/full/IHatsIdUtilities.sol | 68 ++++++ 4 files changed, 451 insertions(+) create mode 100644 contracts/interfaces/hats/full/HatsErrors.sol create mode 100644 contracts/interfaces/hats/full/HatsEvents.sol create mode 100644 contracts/interfaces/hats/full/IHats.sol create mode 100644 contracts/interfaces/hats/full/IHatsIdUtilities.sol diff --git a/contracts/interfaces/hats/full/HatsErrors.sol b/contracts/interfaces/hats/full/HatsErrors.sol new file mode 100644 index 00000000..b592529c --- /dev/null +++ b/contracts/interfaces/hats/full/HatsErrors.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: AGPL-3.0 +// Copyright (C) 2023 Haberdasher Labs +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +pragma solidity >=0.8.13; + +interface HatsErrors { + /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats + /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree` + error NotAdmin(address user, uint256 hatId); + + /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat + error NotHatWearer(); + + /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat + error NotAdminOrWearer(); + + /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached + error AllHatsWorn(uint256 hatId); + + /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin + error MaxLevelsReached(); + + /// @notice Emitted when an attempted hat id has empty intermediate level(s) + error InvalidHatId(); + + /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat + error AlreadyWearingHat(address wearer, uint256 hatId); + + /// @notice Emitted when attempting to mint a non-existant hat + error HatDoesNotExist(uint256 hatId); + + /// @notice Emmitted when attempting to mint or transfer a hat that is not active + error HatNotActive(); + + /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer + error NotEligible(); + + /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module + error NotHatsToggle(); + + /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module + error NotHatsEligibility(); + + /// @notice Emitted when array arguments to a batch function have mismatching lengths + error BatchArrayLengthMismatch(); + + /// @notice Emitted when attempting to mutate or transfer an immutable hat + error Immutable(); + + /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply + error NewMaxSupplyTooLow(); + + /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin + error CircularLinkage(); + + /// @notice Emitted when attempting to link or relink a tophat to a separate tree + error CrossTreeLinkage(); + + /// @notice Emitted when attempting to link a tophat without a request + error LinkageNotRequested(); + + /// @notice Emitted when attempting to unlink a tophat that does not have a wearer + /// @dev This ensures that unlinking never results in a bricked tophat + error InvalidUnlink(); + + /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address + error ZeroAddress(); + + /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters) + /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI + /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()` + error StringTooLong(); +} diff --git a/contracts/interfaces/hats/full/HatsEvents.sol b/contracts/interfaces/hats/full/HatsEvents.sol new file mode 100644 index 00000000..817e4ec1 --- /dev/null +++ b/contracts/interfaces/hats/full/HatsEvents.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: AGPL-3.0 +// Copyright (C) 2023 Haberdasher Labs +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +pragma solidity >=0.8.13; + +interface HatsEvents { + /// @notice Emitted when a new hat is created + /// @param id The id for the new hat + /// @param details A description of the Hat + /// @param maxSupply The total instances of the Hat that can be worn at once + /// @param eligibility The address that can report on the Hat wearer's status + /// @param toggle The address that can deactivate the Hat + /// @param mutable_ Whether the hat's properties are changeable after creation + /// @param imageURI The image uri for this hat and the fallback for its + event HatCreated( + uint256 id, + string details, + uint32 maxSupply, + address eligibility, + address toggle, + bool mutable_, + string imageURI + ); + + /// @notice Emitted when a hat wearer's standing is updated + /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction + /// @param hatId The id of the wearer's hat + /// @param wearer The wearer's address + /// @param wearerStanding Whether the wearer is in good standing for the hat + event WearerStandingChanged( + uint256 hatId, + address wearer, + bool wearerStanding + ); + + /// @notice Emitted when a hat's status is updated + /// @param hatId The id of the hat + /// @param newStatus Whether the hat is active + event HatStatusChanged(uint256 hatId, bool newStatus); + + /// @notice Emitted when a hat's details are updated + /// @param hatId The id of the hat + /// @param newDetails The updated details + event HatDetailsChanged(uint256 hatId, string newDetails); + + /// @notice Emitted when a hat's eligibility module is updated + /// @param hatId The id of the hat + /// @param newEligibility The updated eligibiliy module + event HatEligibilityChanged(uint256 hatId, address newEligibility); + + /// @notice Emitted when a hat's toggle module is updated + /// @param hatId The id of the hat + /// @param newToggle The updated toggle module + event HatToggleChanged(uint256 hatId, address newToggle); + + /// @notice Emitted when a hat's mutability is updated + /// @param hatId The id of the hat + event HatMutabilityChanged(uint256 hatId); + + /// @notice Emitted when a hat's maximum supply is updated + /// @param hatId The id of the hat + /// @param newMaxSupply The updated max supply + event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply); + + /// @notice Emitted when a hat's image URI is updated + /// @param hatId The id of the hat + /// @param newImageURI The updated image URI + event HatImageURIChanged(uint256 hatId, string newImageURI); + + /// @notice Emitted when a tophat linkage is requested by its admin + /// @param domain The domain of the tree tophat to link + /// @param newAdmin The tophat's would-be admin in the parent tree + event TopHatLinkRequested(uint32 domain, uint256 newAdmin); + + /// @notice Emitted when a tophat is linked to a another tree + /// @param domain The domain of the newly-linked tophat + /// @param newAdmin The tophat's new admin in the parent tree + event TopHatLinked(uint32 domain, uint256 newAdmin); +} diff --git a/contracts/interfaces/hats/full/IHats.sol b/contracts/interfaces/hats/full/IHats.sol new file mode 100644 index 00000000..5d0cc188 --- /dev/null +++ b/contracts/interfaces/hats/full/IHats.sol @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: AGPL-3.0 +// Copyright (C) 2023 Haberdasher Labs +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +pragma solidity >=0.8.13; + +import "./IHatsIdUtilities.sol"; +import "./HatsErrors.sol"; +import "./HatsEvents.sol"; + +interface IHats is IHatsIdUtilities, HatsErrors, HatsEvents { + function mintTopHat( + address _target, + string memory _details, + string memory _imageURI + ) external returns (uint256 topHatId); + + function createHat( + uint256 _admin, + string calldata _details, + uint32 _maxSupply, + address _eligibility, + address _toggle, + bool _mutable, + string calldata _imageURI + ) external returns (uint256 newHatId); + + function batchCreateHats( + uint256[] calldata _admins, + string[] calldata _details, + uint32[] calldata _maxSupplies, + address[] memory _eligibilityModules, + address[] memory _toggleModules, + bool[] calldata _mutables, + string[] calldata _imageURIs + ) external returns (bool success); + + function getNextId(uint256 _admin) external view returns (uint256 nextId); + + function mintHat( + uint256 _hatId, + address _wearer + ) external returns (bool success); + + function batchMintHats( + uint256[] calldata _hatIds, + address[] calldata _wearers + ) external returns (bool success); + + function setHatStatus( + uint256 _hatId, + bool _newStatus + ) external returns (bool toggled); + + function checkHatStatus(uint256 _hatId) external returns (bool toggled); + + function setHatWearerStatus( + uint256 _hatId, + address _wearer, + bool _eligible, + bool _standing + ) external returns (bool updated); + + function checkHatWearerStatus( + uint256 _hatId, + address _wearer + ) external returns (bool updated); + + function renounceHat(uint256 _hatId) external; + + function transferHat(uint256 _hatId, address _from, address _to) external; + + /*////////////////////////////////////////////////////////////// + HATS ADMIN FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function makeHatImmutable(uint256 _hatId) external; + + function changeHatDetails( + uint256 _hatId, + string memory _newDetails + ) external; + + function changeHatEligibility( + uint256 _hatId, + address _newEligibility + ) external; + + function changeHatToggle(uint256 _hatId, address _newToggle) external; + + function changeHatImageURI( + uint256 _hatId, + string memory _newImageURI + ) external; + + function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external; + + function requestLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat + ) external; + + function approveLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external; + + function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external; + + function relinkTopHatWithinTree( + uint32 _topHatDomain, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external; + + /*////////////////////////////////////////////////////////////// + VIEW FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function viewHat( + uint256 _hatId + ) + external + view + returns ( + string memory details, + uint32 maxSupply, + uint32 supply, + address eligibility, + address toggle, + string memory imageURI, + uint16 lastHatId, + bool mutable_, + bool active + ); + + function isWearerOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isWearer); + + function isAdminOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isAdmin); + + function isInGoodStanding( + address _wearer, + uint256 _hatId + ) external view returns (bool standing); + + function isEligible( + address _wearer, + uint256 _hatId + ) external view returns (bool eligible); + + function getHatEligibilityModule( + uint256 _hatId + ) external view returns (address eligibility); + + function getHatToggleModule( + uint256 _hatId + ) external view returns (address toggle); + + function getHatMaxSupply( + uint256 _hatId + ) external view returns (uint32 maxSupply); + + function hatSupply(uint256 _hatId) external view returns (uint32 supply); + + function getImageURIForHat( + uint256 _hatId + ) external view returns (string memory _uri); + + function balanceOf( + address wearer, + uint256 hatId + ) external view returns (uint256 balance); + + function balanceOfBatch( + address[] calldata _wearers, + uint256[] calldata _hatIds + ) external view returns (uint256[] memory); + + function uri(uint256 id) external view returns (string memory _uri); +} diff --git a/contracts/interfaces/hats/full/IHatsIdUtilities.sol b/contracts/interfaces/hats/full/IHatsIdUtilities.sol new file mode 100644 index 00000000..dcf640fd --- /dev/null +++ b/contracts/interfaces/hats/full/IHatsIdUtilities.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: AGPL-3.0 +// Copyright (C) 2023 Haberdasher Labs +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +pragma solidity >=0.8.13; + +interface IHatsIdUtilities { + function buildHatId( + uint256 _admin, + uint16 _newHat + ) external pure returns (uint256 id); + + function getHatLevel(uint256 _hatId) external view returns (uint32 level); + + function getLocalHatLevel( + uint256 _hatId + ) external pure returns (uint32 level); + + function isTopHat(uint256 _hatId) external view returns (bool _topHat); + + function isLocalTopHat( + uint256 _hatId + ) external pure returns (bool _localTopHat); + + function isValidHatId( + uint256 _hatId + ) external view returns (bool validHatId); + + function getAdminAtLevel( + uint256 _hatId, + uint32 _level + ) external view returns (uint256 admin); + + function getAdminAtLocalLevel( + uint256 _hatId, + uint32 _level + ) external pure returns (uint256 admin); + + function getTopHatDomain( + uint256 _hatId + ) external view returns (uint32 domain); + + function getTippyTopHatDomain( + uint32 _topHatDomain + ) external view returns (uint32 domain); + + function noCircularLinkage( + uint32 _topHatDomain, + uint256 _linkedAdmin + ) external view returns (bool notCircular); + + function sameTippyTopHatDomain( + uint32 _topHatDomain, + uint256 _newAdminHat + ) external view returns (bool sameDomain); +} From dca553be7fd1baa94546db79211057eb9ff8786b Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:08:57 -0400 Subject: [PATCH 066/206] Rename IHatModuleFactory to IHatsModuleFactory, place it in Hats directory, make sure the interface and mock implementation are complete --- contracts/DecentHats_0_2_0.sol | 2 +- contracts/interfaces/IHatModuleFactory.sol | 20 ------- .../hats/full/IHatsModuleFactory.sol | 56 +++++++++++++++++++ contracts/mocks/MockHatsModuleFactory.sol | 21 ++++++- 4 files changed, 77 insertions(+), 22 deletions(-) delete mode 100644 contracts/interfaces/IHatModuleFactory.sol create mode 100644 contracts/interfaces/hats/full/IHatsModuleFactory.sol diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index 4a78de51..a3b68312 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -9,7 +9,7 @@ import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/IHats.sol"; import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; -import {IHatsModuleFactory} from "./interfaces/IHatModuleFactory.sol"; +import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; diff --git a/contracts/interfaces/IHatModuleFactory.sol b/contracts/interfaces/IHatModuleFactory.sol deleted file mode 100644 index 46c74ac0..00000000 --- a/contracts/interfaces/IHatModuleFactory.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - - -interface IHatsModuleFactory { - function createHatsModule( - address _implementation, - uint256 _hatId, - bytes calldata _otherImmutableArgs, - bytes calldata _initData, - uint256 _saltNonce - ) external returns (address _instance); - - function getHatsModuleAddress( - address _implementation, - uint256 _hatId, - bytes calldata _otherImmutableArgs, - uint256 _saltNonce - ) external view returns (address); -} diff --git a/contracts/interfaces/hats/full/IHatsModuleFactory.sol b/contracts/interfaces/hats/full/IHatsModuleFactory.sol new file mode 100644 index 00000000..1aa8804d --- /dev/null +++ b/contracts/interfaces/hats/full/IHatsModuleFactory.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +interface IHatsModuleFactory { + error HatsModuleFactory_ModuleAlreadyDeployed( + address implementation, + uint256 hatId, + bytes otherImmutableArgs, + uint256 saltNonce + ); + + error BatchArrayLengthMismatch(); + + event HatsModuleFactory_ModuleDeployed( + address implementation, + address instance, + uint256 hatId, + bytes otherImmutableArgs, + bytes initData, + uint256 saltNonce + ); + + function HATS() external view returns (address); + + function version() external view returns (string memory); + + function createHatsModule( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + bytes calldata _initData, + uint256 _saltNonce + ) external returns (address _instance); + + function batchCreateHatsModule( + address[] calldata _implementations, + uint256[] calldata _hatIds, + bytes[] calldata _otherImmutableArgsArray, + bytes[] calldata _initDataArray, + uint256[] calldata _saltNonces + ) external returns (bool success); + + function getHatsModuleAddress( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + uint256 _saltNonce + ) external view returns (address); + + function deployed( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + uint256 _saltNonce + ) external view returns (bool); +} diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol index 2bfb92ba..944d3401 100644 --- a/contracts/mocks/MockHatsModuleFactory.sol +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IHatsModuleFactory} from "../interfaces/IHatModuleFactory.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/full/IHatsModuleFactory.sol"; contract MockHatsModuleFactory is IHatsModuleFactory { function createHatsModule( @@ -33,4 +33,23 @@ contract MockHatsModuleFactory is IHatsModuleFactory { _saltNonce; return address(0); } + + function HATS() external view override returns (address) {} + + function version() external view override returns (string memory) {} + + function batchCreateHatsModule( + address[] calldata _implementations, + uint256[] calldata _hatIds, + bytes[] calldata _otherImmutableArgsArray, + bytes[] calldata _initDataArray, + uint256[] calldata _saltNonces + ) external override returns (bool success) {} + + function deployed( + address _implementation, + uint256 _hatId, + bytes calldata _otherImmutableArgs, + uint256 _saltNonce + ) external view override returns (bool) {} } From 49ef5d7bf2e9194fe16a8e563c0215c5eb5b16c6 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:14:02 -0400 Subject: [PATCH 067/206] Move IHatsElectionsElegibility into "full" directory --- contracts/DecentAutonomousAdmin.sol | 2 +- contracts/DecentHats_0_2_0.sol | 2 +- .../interfaces/hats/{ => full}/IHatsElectionEligibility.sol | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename contracts/interfaces/hats/{ => full}/IHatsElectionEligibility.sol (100%) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 21915faa..4f48c4df 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; import {IHats} from "./interfaces/hats/IHats.sol"; -import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; +import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; contract DecentAutonomousAdmin { diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index a3b68312..f93c06b9 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -10,7 +10,7 @@ import {IHats} from "./interfaces/hats/IHats.sol"; import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; -import {IHatsElectionEligibility} from "./interfaces/hats/IHatsElectionEligibility.sol"; +import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; diff --git a/contracts/interfaces/hats/IHatsElectionEligibility.sol b/contracts/interfaces/hats/full/IHatsElectionEligibility.sol similarity index 100% rename from contracts/interfaces/hats/IHatsElectionEligibility.sol rename to contracts/interfaces/hats/full/IHatsElectionEligibility.sol From 1633f2662fb0ad12c6d4b6c7a8c4a53708d10a19 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:16:59 -0400 Subject: [PATCH 068/206] If you don't need to use a variable in a function just delete the name of it in the input params --- contracts/mocks/MockHatsAdmin.sol | 38 ++++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/contracts/mocks/MockHatsAdmin.sol b/contracts/mocks/MockHatsAdmin.sol index 914c0d30..a32683ef 100644 --- a/contracts/mocks/MockHatsAdmin.sol +++ b/contracts/mocks/MockHatsAdmin.sol @@ -11,33 +11,22 @@ contract MockHatsAutoAdmin is IHats { event HatCreated(uint256 hatId); function mintTopHat( - address _target, - string memory _details, - string memory _imageURI + address, + string memory, + string memory ) external pure returns (uint256 topHatId) { - // Silence unused variable warnings - _target; - _details; - _imageURI; return 0; } function createHat( - uint256 _admin, - string calldata _details, - uint32 _maxSupply, + uint256, + string calldata, + uint32, address _eligibility, - address _toggle, - bool _mutable, - string calldata _imageURI + address, + bool, + string calldata ) external returns (uint256 newHatId) { - // Silence unused variable warnings - _admin; - _details; - _maxSupply; - _toggle; - _mutable; - _imageURI; hatId++; eligibility[hatId] = _eligibility; emit HatCreated(hatId); @@ -67,15 +56,16 @@ contract MockHatsAutoAdmin is IHats { function transferHat( uint256 _hatId, - address from, + address, address to ) external override { - // Silence unused variable warnings - from; wearer[_hatId] = to; } - function changeHatEligibility(uint256 _hatId, address _newEligibility) external override { + function changeHatEligibility( + uint256 _hatId, + address _newEligibility + ) external override { eligibility[_hatId] = _newEligibility; } } From 004e4a33177adae705187e7a449c64733406e4b5 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:18:08 -0400 Subject: [PATCH 069/206] Finish implementing full Hats interface in MockHatsAdmin --- contracts/mocks/MockHatsAdmin.sol | 211 +++++++++++++++++++++++++++++- 1 file changed, 210 insertions(+), 1 deletion(-) diff --git a/contracts/mocks/MockHatsAdmin.sol b/contracts/mocks/MockHatsAdmin.sol index a32683ef..9fc250b4 100644 --- a/contracts/mocks/MockHatsAdmin.sol +++ b/contracts/mocks/MockHatsAdmin.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -import "../interfaces/hats/IHats.sol"; +import {IHats} from "../interfaces/hats/full/IHats.sol"; contract MockHatsAutoAdmin is IHats { uint256 hatId = 0; @@ -68,4 +68,213 @@ contract MockHatsAutoAdmin is IHats { ) external override { eligibility[_hatId] = _newEligibility; } + + function buildHatId( + uint256 _admin, + uint16 _newHat + ) external pure override returns (uint256 id) {} + + function getHatLevel( + uint256 _hatId + ) external view override returns (uint32 level) {} + + function getLocalHatLevel( + uint256 _hatId + ) external pure override returns (uint32 level) {} + + function isTopHat( + uint256 _hatId + ) external view override returns (bool _topHat) {} + + function isLocalTopHat( + uint256 _hatId + ) external pure override returns (bool _localTopHat) {} + + function isValidHatId( + uint256 _hatId + ) external view override returns (bool validHatId) {} + + function getAdminAtLevel( + uint256 _hatId, + uint32 _level + ) external view override returns (uint256 admin) {} + + function getAdminAtLocalLevel( + uint256 _hatId, + uint32 _level + ) external pure override returns (uint256 admin) {} + + function getTopHatDomain( + uint256 _hatId + ) external view override returns (uint32 domain) {} + + function getTippyTopHatDomain( + uint32 _topHatDomain + ) external view override returns (uint32 domain) {} + + function noCircularLinkage( + uint32 _topHatDomain, + uint256 _linkedAdmin + ) external view override returns (bool notCircular) {} + + function sameTippyTopHatDomain( + uint32 _topHatDomain, + uint256 _newAdminHat + ) external view override returns (bool sameDomain) {} + + function batchCreateHats( + uint256[] calldata _admins, + string[] calldata _details, + uint32[] calldata _maxSupplies, + address[] memory _eligibilityModules, + address[] memory _toggleModules, + bool[] calldata _mutables, + string[] calldata _imageURIs + ) external override returns (bool success) {} + + function getNextId( + uint256 _admin + ) external view override returns (uint256 nextId) {} + + function batchMintHats( + uint256[] calldata _hatIds, + address[] calldata _wearers + ) external override returns (bool success) {} + + function setHatStatus( + uint256 _hatId, + bool _newStatus + ) external override returns (bool toggled) {} + + function checkHatStatus( + uint256 _hatId + ) external override returns (bool toggled) {} + + function setHatWearerStatus( + uint256 _hatId, + address _wearer, + bool _eligible, + bool _standing + ) external override returns (bool updated) {} + + function checkHatWearerStatus( + uint256 _hatId, + address _wearer + ) external override returns (bool updated) {} + + function renounceHat(uint256 _hatId) external override {} + + function makeHatImmutable(uint256 _hatId) external override {} + + function changeHatDetails( + uint256 _hatId, + string memory _newDetails + ) external override {} + + function changeHatToggle( + uint256 _hatId, + address _newToggle + ) external override {} + + function changeHatImageURI( + uint256 _hatId, + string memory _newImageURI + ) external override {} + + function changeHatMaxSupply( + uint256 _hatId, + uint32 _newMaxSupply + ) external override {} + + function requestLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat + ) external override {} + + function approveLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external override {} + + function unlinkTopHatFromTree( + uint32 _topHatId, + address _wearer + ) external override {} + + function relinkTopHatWithinTree( + uint32 _topHatDomain, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external override {} + + function viewHat( + uint256 _hatId + ) + external + view + override + returns ( + string memory _details, + uint32 _maxSupply, + uint32 _supply, + address _eligibility, + address _toggle, + string memory _imageURI, + uint16 _lastHatId, + bool _mutable, + bool _active + ) + {} + + function isAdminOfHat( + address _user, + uint256 _hatId + ) external view override returns (bool isAdmin) {} + + function isInGoodStanding( + address _wearer, + uint256 _hatId + ) external view override returns (bool standing) {} + + function isEligible( + address _wearer, + uint256 _hatId + ) external view override returns (bool eligible) {} + + function getHatToggleModule( + uint256 _hatId + ) external view override returns (address toggle) {} + + function getHatMaxSupply( + uint256 _hatId + ) external view override returns (uint32 maxSupply) {} + + function hatSupply( + uint256 _hatId + ) external view override returns (uint32 supply) {} + + function getImageURIForHat( + uint256 _hatId + ) external view override returns (string memory _uri) {} + + function balanceOf( + address _wearer, + uint256 _hatId + ) external view override returns (uint256 balance) {} + + function balanceOfBatch( + address[] calldata _wearers, + uint256[] calldata _hatIds + ) external view override returns (uint256[] memory) {} + + function uri( + uint256 id + ) external view override returns (string memory _uri) {} } From 71ac995dfac7d2916af553bae5facc57cd7f5f9c Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:18:35 -0400 Subject: [PATCH 070/206] Use "full" IHats interface in DecentAutonomousAdmin and DecentHats_0_2_0 --- contracts/DecentAutonomousAdmin.sol | 2 +- contracts/DecentHats_0_2_0.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 4f48c4df..becb8746 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -import {IHats} from "./interfaces/hats/IHats.sol"; +import {IHats} from "./interfaces/hats/full/IHats.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index f93c06b9..161dfd4c 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -6,7 +6,7 @@ import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/IHats.sol"; +import {IHats} from "./interfaces/hats/full/IHats.sol"; import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; From f90ac5ac46f7770af415cab71e1f5684e9e30dcf Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:18:45 -0400 Subject: [PATCH 071/206] Revert changes to original IHats interface --- contracts/interfaces/hats/IHats.sol | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index 0f4218b7..c460c46d 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -39,15 +39,4 @@ interface IHats { ) external returns (bool success); function transferHat(uint256 _hatId, address _from, address _to) external; - - function getHatEligibilityModule( - uint256 _hatId - ) external view returns (address eligibility); - - function isWearerOfHat( - address _user, - uint256 _hatId - ) external view returns (bool isWearer); - - function changeHatEligibility(uint256 _hatId, address _newEligibility) external; } From 0ce7bbd365a31f0ed250a5b8267e56d5144db63a Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:20:48 -0400 Subject: [PATCH 072/206] Revert change to DecentHats_0_1_0 contract -- this actually does cause a difference in compiled bytecode! --- contracts/DecentHats_0_1_0.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index 5d29a42e..c00dadaa 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -247,4 +247,4 @@ contract DecentHats_0_1_0 { params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); } -} \ No newline at end of file +} From 80981eec889c0bf86653f3380c630314827e05cc Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:29:00 -0400 Subject: [PATCH 073/206] Remove unused import from DecentHats_0_2_0 --- contracts/DecentHats_0_2_0.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index 161dfd4c..ad05cea1 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -11,7 +11,6 @@ import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.so import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; -import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; contract DecentHats_0_2_0 { From 84e6c4df75837a05797b77bfa2209078ed2e627e Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 15:34:21 -0400 Subject: [PATCH 074/206] Add deployment script --- deploy/core/018_deploy_DecentSablierStreamManagement.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 deploy/core/018_deploy_DecentSablierStreamManagement.ts diff --git a/deploy/core/018_deploy_DecentSablierStreamManagement.ts b/deploy/core/018_deploy_DecentSablierStreamManagement.ts new file mode 100644 index 00000000..fb33345a --- /dev/null +++ b/deploy/core/018_deploy_DecentSablierStreamManagement.ts @@ -0,0 +1,9 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + await deployNonUpgradeable(hre, "DecentSablierStreamManagement"); +}; + +export default func; From c38c0b624c163b8ff51e667b24b4064ec4cfc126 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 17:23:38 -0400 Subject: [PATCH 075/206] Update Sablier contracts to their actual solidity pragma --- contracts/interfaces/sablier/full/IAdminable.sol | 2 +- contracts/interfaces/sablier/full/IERC4096.sol | 2 +- contracts/interfaces/sablier/full/ISablierV2Lockup.sol | 2 +- contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol | 2 +- contracts/interfaces/sablier/full/types/DataTypes.sol | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/interfaces/sablier/full/IAdminable.sol b/contracts/interfaces/sablier/full/IAdminable.sol index e5ee0956..62a13d1a 100644 --- a/contracts/interfaces/sablier/full/IAdminable.sol +++ b/contracts/interfaces/sablier/full/IAdminable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; /// @title IAdminable /// @notice Contract module that provides a basic access control mechanism, with an admin that can be diff --git a/contracts/interfaces/sablier/full/IERC4096.sol b/contracts/interfaces/sablier/full/IERC4096.sol index 29bcc6ea..017e3b59 100644 --- a/contracts/interfaces/sablier/full/IERC4096.sol +++ b/contracts/interfaces/sablier/full/IERC4096.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol) -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; diff --git a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol index 8e5b21e3..af593567 100644 --- a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol +++ b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; import {IERC4906} from "./IERC4096.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol index 49fec926..1d03bc95 100644 --- a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol +++ b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; diff --git a/contracts/interfaces/sablier/full/types/DataTypes.sol b/contracts/interfaces/sablier/full/types/DataTypes.sol index b7b50c59..c150ccff 100644 --- a/contracts/interfaces/sablier/full/types/DataTypes.sol +++ b/contracts/interfaces/sablier/full/types/DataTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {UD2x18} from "@prb/math/src/UD2x18.sol"; From ee3478cc5b76e4bc66a2cc7eb02c73ac0849c118 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 17:27:23 -0400 Subject: [PATCH 076/206] Update Sablier contracts to their actual solidity pragma --- contracts/interfaces/sablier/full/IAdminable.sol | 2 +- contracts/interfaces/sablier/full/IERC4096.sol | 2 +- contracts/interfaces/sablier/full/ISablierV2Lockup.sol | 2 +- contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol | 2 +- contracts/interfaces/sablier/full/types/DataTypes.sol | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/interfaces/sablier/full/IAdminable.sol b/contracts/interfaces/sablier/full/IAdminable.sol index e5ee0956..62a13d1a 100644 --- a/contracts/interfaces/sablier/full/IAdminable.sol +++ b/contracts/interfaces/sablier/full/IAdminable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; /// @title IAdminable /// @notice Contract module that provides a basic access control mechanism, with an admin that can be diff --git a/contracts/interfaces/sablier/full/IERC4096.sol b/contracts/interfaces/sablier/full/IERC4096.sol index 29bcc6ea..017e3b59 100644 --- a/contracts/interfaces/sablier/full/IERC4096.sol +++ b/contracts/interfaces/sablier/full/IERC4096.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol) -pragma solidity ^0.8.19; +pragma solidity ^0.8.20; import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; diff --git a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol index 8e5b21e3..af593567 100644 --- a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol +++ b/contracts/interfaces/sablier/full/ISablierV2Lockup.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; import {IERC4906} from "./IERC4096.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol index 49fec926..1d03bc95 100644 --- a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol +++ b/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; diff --git a/contracts/interfaces/sablier/full/types/DataTypes.sol b/contracts/interfaces/sablier/full/types/DataTypes.sol index b7b50c59..c150ccff 100644 --- a/contracts/interfaces/sablier/full/types/DataTypes.sol +++ b/contracts/interfaces/sablier/full/types/DataTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.8.19; +pragma solidity >=0.8.22; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {UD2x18} from "@prb/math/src/UD2x18.sol"; From 518e0532cab792bbdbb0e58fd317c1c71d51e774 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 17:24:06 -0400 Subject: [PATCH 077/206] Support solidity version 0.8.28 in hardhat config --- hardhat.config.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 85d222f6..9f896ddf 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -13,13 +13,26 @@ const dummyPrivateKey = const config: HardhatUserConfig = { solidity: { - version: "0.8.19", - settings: { - optimizer: { - enabled: true, - runs: 200, + compilers: [ + { + version: "0.8.19", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, }, - }, + { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + ], }, dependencyCompiler: { paths: [ From 6a45c949dde79eae79575064931df30821357be7 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 17:29:49 -0400 Subject: [PATCH 078/206] Use solidity version 0.8.28 for new contracts --- contracts/DecentAutonomousAdmin.sol | 3 ++- contracts/DecentHats_0_2_0.sol | 2 +- contracts/mocks/MockSablierV2LockupLinear.sol | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index becb8746..921f871e 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity =0.8.19; +pragma solidity 0.8.28; + import {IHats} from "./interfaces/hats/full/IHats.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats_0_2_0.sol index ad05cea1..29160a68 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats_0_2_0.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity =0.8.19; +pragma solidity 0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 99ec6c7b..c4694ed9 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity =0.8.19; +pragma solidity 0.8.28; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {UD60x18} from "@prb/math/src/UD60x18.sol"; From cf640158a1b39627f383522ebc809ce6c294c691 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 17:24:06 -0400 Subject: [PATCH 079/206] Support solidity version 0.8.28 in hardhat config --- hardhat.config.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 85d222f6..9f896ddf 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -13,13 +13,26 @@ const dummyPrivateKey = const config: HardhatUserConfig = { solidity: { - version: "0.8.19", - settings: { - optimizer: { - enabled: true, - runs: 200, + compilers: [ + { + version: "0.8.19", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, }, - }, + { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + ], }, dependencyCompiler: { paths: [ From 7348526ccc44a8de15b40328e5c2ba453b68d5ec Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 9 Oct 2024 17:23:55 -0400 Subject: [PATCH 080/206] Make DecentSablierStreamManagement solidity pragma use version 0.8.28 --- contracts/DecentSablierStreamManagement.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index dcbafe7e..380d9b85 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity =0.8.19; +pragma solidity 0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; From d75ed1cace0ec2f9c3788848bf31d5f9c10c32a2 Mon Sep 17 00:00:00 2001 From: Kellar Date: Thu, 10 Oct 2024 13:42:50 +0100 Subject: [PATCH 081/206] Deploy to sepolia --- .../DecentSablierStreamManagement.json | 100 +++++ .../4511b61209438ca20d2458493e70bb24.json | 351 ++++++++++++++++++ 2 files changed, 451 insertions(+) create mode 100644 deployments/sepolia/DecentSablierStreamManagement.json create mode 100644 deployments/sepolia/solcInputs/4511b61209438ca20d2458493e70bb24.json diff --git a/deployments/sepolia/DecentSablierStreamManagement.json b/deployments/sepolia/DecentSablierStreamManagement.json new file mode 100644 index 00000000..3779fae4 --- /dev/null +++ b/deployments/sepolia/DecentSablierStreamManagement.json @@ -0,0 +1,100 @@ +{ + "address": "0x5874bf327bA5b78b2371b13eB414B66179591d34", + "abi": [ + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + } + ], + "name": "cancelStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientHatAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawMaxFromStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", + "receipt": { + "to": null, + "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", + "contractAddress": "0x5874bf327bA5b78b2371b13eB414B66179591d34", + "transactionIndex": 72, + "gasUsed": "384441", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2d90032ee5f61b968f6e38065b8dab930b88bb292edc0059448acc5e02903a4a", + "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", + "logs": [], + "blockNumber": 6850325, + "cumulativeGasUsed": "8716271", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "4511b61209438ca20d2458493e70bb24", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/sepolia/solcInputs/4511b61209438ca20d2458493e70bb24.json b/deployments/sepolia/solcInputs/4511b61209438ca20d2458493e70bb24.json new file mode 100644 index 00000000..c068a9c4 --- /dev/null +++ b/deployments/sepolia/solcInputs/4511b61209438ca20d2458493e70bb24.json @@ -0,0 +1,351 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/core/Module.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/governance/utils/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@prb/math/src/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" + }, + "@prb/math/src/sd1x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd1x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/sd1x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" + }, + "@prb/math/src/sd1x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" + }, + "@prb/math/src/sd59x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd59x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" + }, + "@prb/math/src/sd59x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" + }, + "@prb/math/src/sd59x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/sd59x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" + }, + "@prb/math/src/sd59x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" + }, + "@prb/math/src/UD2x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud2x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud2x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/ud2x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" + }, + "@prb/math/src/ud2x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" + }, + "@prb/math/src/UD60x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud60x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud60x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" + }, + "@prb/math/src/ud60x18/Conversions.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" + }, + "@prb/math/src/ud60x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" + }, + "@prb/math/src/ud60x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/ud60x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" + }, + "@prb/math/src/ud60x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" + }, + "contracts/DecentSablierStreamManagement.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/full/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/full/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/full/IAdminable.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" + }, + "contracts/interfaces/sablier/full/IERC4096.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2Lockup.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" + }, + "contracts/interfaces/sablier/full/types/DataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + }, + "contracts/mocks/ERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" + }, + "contracts/mocks/MockContract.sol": { + "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" + }, + "contracts/mocks/MockLockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file From bdfe98f3bd564166d0bb722ea836c19e195112e9 Mon Sep 17 00:00:00 2001 From: Kellar Date: Thu, 10 Oct 2024 17:35:35 +0100 Subject: [PATCH 082/206] Deploy contracts --- .../base/DecentSablierStreamManagement.json | 100 +++++ .../4511b61209438ca20d2458493e70bb24.json | 351 ++++++++++++++++++ .../DecentSablierStreamManagement.json | 100 +++++ .../4511b61209438ca20d2458493e70bb24.json | 351 ++++++++++++++++++ .../DecentSablierStreamManagement.json | 100 +++++ .../4511b61209438ca20d2458493e70bb24.json | 351 ++++++++++++++++++ .../DecentSablierStreamManagement.json | 116 ++++++ .../4511b61209438ca20d2458493e70bb24.json | 351 ++++++++++++++++++ 8 files changed, 1820 insertions(+) create mode 100644 deployments/base/DecentSablierStreamManagement.json create mode 100644 deployments/base/solcInputs/4511b61209438ca20d2458493e70bb24.json create mode 100644 deployments/mainnet/DecentSablierStreamManagement.json create mode 100644 deployments/mainnet/solcInputs/4511b61209438ca20d2458493e70bb24.json create mode 100644 deployments/optimism/DecentSablierStreamManagement.json create mode 100644 deployments/optimism/solcInputs/4511b61209438ca20d2458493e70bb24.json create mode 100644 deployments/polygon/DecentSablierStreamManagement.json create mode 100644 deployments/polygon/solcInputs/4511b61209438ca20d2458493e70bb24.json diff --git a/deployments/base/DecentSablierStreamManagement.json b/deployments/base/DecentSablierStreamManagement.json new file mode 100644 index 00000000..a4695b56 --- /dev/null +++ b/deployments/base/DecentSablierStreamManagement.json @@ -0,0 +1,100 @@ +{ + "address": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", + "abi": [ + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + } + ], + "name": "cancelStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientHatAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawMaxFromStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xe8c58dad912fb02c5477f4d221e92994a80fbc2b8d26c05da7f394582c9451bb", + "receipt": { + "to": null, + "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", + "contractAddress": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", + "transactionIndex": 95, + "gasUsed": "384441", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xe2639b222eafa8314a402b10a98cab3ca4ca1143cbfdf696850f1a07b2a4256a", + "transactionHash": "0xe8c58dad912fb02c5477f4d221e92994a80fbc2b8d26c05da7f394582c9451bb", + "logs": [], + "blockNumber": 20894292, + "cumulativeGasUsed": "20584732", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "4511b61209438ca20d2458493e70bb24", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/solcInputs/4511b61209438ca20d2458493e70bb24.json b/deployments/base/solcInputs/4511b61209438ca20d2458493e70bb24.json new file mode 100644 index 00000000..c068a9c4 --- /dev/null +++ b/deployments/base/solcInputs/4511b61209438ca20d2458493e70bb24.json @@ -0,0 +1,351 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/core/Module.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/governance/utils/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@prb/math/src/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" + }, + "@prb/math/src/sd1x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd1x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/sd1x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" + }, + "@prb/math/src/sd1x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" + }, + "@prb/math/src/sd59x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd59x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" + }, + "@prb/math/src/sd59x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" + }, + "@prb/math/src/sd59x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/sd59x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" + }, + "@prb/math/src/sd59x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" + }, + "@prb/math/src/UD2x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud2x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud2x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/ud2x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" + }, + "@prb/math/src/ud2x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" + }, + "@prb/math/src/UD60x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud60x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud60x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" + }, + "@prb/math/src/ud60x18/Conversions.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" + }, + "@prb/math/src/ud60x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" + }, + "@prb/math/src/ud60x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/ud60x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" + }, + "@prb/math/src/ud60x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" + }, + "contracts/DecentSablierStreamManagement.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/full/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/full/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/full/IAdminable.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" + }, + "contracts/interfaces/sablier/full/IERC4096.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2Lockup.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" + }, + "contracts/interfaces/sablier/full/types/DataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + }, + "contracts/mocks/ERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" + }, + "contracts/mocks/MockContract.sol": { + "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" + }, + "contracts/mocks/MockLockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/DecentSablierStreamManagement.json b/deployments/mainnet/DecentSablierStreamManagement.json new file mode 100644 index 00000000..19664031 --- /dev/null +++ b/deployments/mainnet/DecentSablierStreamManagement.json @@ -0,0 +1,100 @@ +{ + "address": "0x84D96C7cD9F1Ea7da6d37054b0A6762be949df2B", + "abi": [ + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + } + ], + "name": "cancelStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientHatAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawMaxFromStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x1b8f61e0172a4044a4021ccd9ce6fd30095c568778c829d2d16959fd894cf7aa", + "receipt": { + "to": null, + "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", + "contractAddress": "0x84D96C7cD9F1Ea7da6d37054b0A6762be949df2B", + "transactionIndex": 94, + "gasUsed": "384441", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xdde1b87de37ca61887609fd8695e07b689dfd85acc88755aca2b61aeae22ded2", + "transactionHash": "0x1b8f61e0172a4044a4021ccd9ce6fd30095c568778c829d2d16959fd894cf7aa", + "logs": [], + "blockNumber": 20936434, + "cumulativeGasUsed": "8659131", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "4511b61209438ca20d2458493e70bb24", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/solcInputs/4511b61209438ca20d2458493e70bb24.json b/deployments/mainnet/solcInputs/4511b61209438ca20d2458493e70bb24.json new file mode 100644 index 00000000..c068a9c4 --- /dev/null +++ b/deployments/mainnet/solcInputs/4511b61209438ca20d2458493e70bb24.json @@ -0,0 +1,351 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/core/Module.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/governance/utils/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@prb/math/src/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" + }, + "@prb/math/src/sd1x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd1x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/sd1x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" + }, + "@prb/math/src/sd1x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" + }, + "@prb/math/src/sd59x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd59x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" + }, + "@prb/math/src/sd59x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" + }, + "@prb/math/src/sd59x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/sd59x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" + }, + "@prb/math/src/sd59x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" + }, + "@prb/math/src/UD2x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud2x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud2x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/ud2x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" + }, + "@prb/math/src/ud2x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" + }, + "@prb/math/src/UD60x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud60x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud60x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" + }, + "@prb/math/src/ud60x18/Conversions.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" + }, + "@prb/math/src/ud60x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" + }, + "@prb/math/src/ud60x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/ud60x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" + }, + "@prb/math/src/ud60x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" + }, + "contracts/DecentSablierStreamManagement.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/full/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/full/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/full/IAdminable.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" + }, + "contracts/interfaces/sablier/full/IERC4096.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2Lockup.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" + }, + "contracts/interfaces/sablier/full/types/DataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + }, + "contracts/mocks/ERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" + }, + "contracts/mocks/MockContract.sol": { + "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" + }, + "contracts/mocks/MockLockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/DecentSablierStreamManagement.json b/deployments/optimism/DecentSablierStreamManagement.json new file mode 100644 index 00000000..5681bc6e --- /dev/null +++ b/deployments/optimism/DecentSablierStreamManagement.json @@ -0,0 +1,100 @@ +{ + "address": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", + "abi": [ + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + } + ], + "name": "cancelStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientHatAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawMaxFromStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xa70b0fd93d4afeb76e06826853681fb456c1c99e5005adf1904d7dce18e311bb", + "receipt": { + "to": null, + "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", + "contractAddress": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", + "transactionIndex": 13, + "gasUsed": "384441", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8d4430fb1ba84139a233692228da3d47eda1e21063cbe56f4c01501a37926b2b", + "transactionHash": "0xa70b0fd93d4afeb76e06826853681fb456c1c99e5005adf1904d7dce18e311bb", + "logs": [], + "blockNumber": 126489616, + "cumulativeGasUsed": "2581689", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "4511b61209438ca20d2458493e70bb24", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/4511b61209438ca20d2458493e70bb24.json b/deployments/optimism/solcInputs/4511b61209438ca20d2458493e70bb24.json new file mode 100644 index 00000000..c068a9c4 --- /dev/null +++ b/deployments/optimism/solcInputs/4511b61209438ca20d2458493e70bb24.json @@ -0,0 +1,351 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/core/Module.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/governance/utils/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@prb/math/src/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" + }, + "@prb/math/src/sd1x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd1x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/sd1x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" + }, + "@prb/math/src/sd1x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" + }, + "@prb/math/src/sd59x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd59x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" + }, + "@prb/math/src/sd59x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" + }, + "@prb/math/src/sd59x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/sd59x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" + }, + "@prb/math/src/sd59x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" + }, + "@prb/math/src/UD2x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud2x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud2x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/ud2x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" + }, + "@prb/math/src/ud2x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" + }, + "@prb/math/src/UD60x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud60x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud60x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" + }, + "@prb/math/src/ud60x18/Conversions.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" + }, + "@prb/math/src/ud60x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" + }, + "@prb/math/src/ud60x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/ud60x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" + }, + "@prb/math/src/ud60x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" + }, + "contracts/DecentSablierStreamManagement.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/full/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/full/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/full/IAdminable.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" + }, + "contracts/interfaces/sablier/full/IERC4096.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2Lockup.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" + }, + "contracts/interfaces/sablier/full/types/DataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + }, + "contracts/mocks/ERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" + }, + "contracts/mocks/MockContract.sol": { + "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" + }, + "contracts/mocks/MockLockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/DecentSablierStreamManagement.json b/deployments/polygon/DecentSablierStreamManagement.json new file mode 100644 index 00000000..795367d5 --- /dev/null +++ b/deployments/polygon/DecentSablierStreamManagement.json @@ -0,0 +1,116 @@ +{ + "address": "0xcd6c149b3C0FE7284005869fa15080e85887c8F1", + "abi": [ + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + } + ], + "name": "cancelStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientHatAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawMaxFromStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x79bc48a59de268be4623c5a7a2e419da30b95b8bb7119f60e59f097c5aa30dba", + "receipt": { + "to": null, + "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", + "contractAddress": "0xcd6c149b3C0FE7284005869fa15080e85887c8F1", + "transactionIndex": 26, + "gasUsed": "384441", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000008000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000800100080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000100004000000000000000000200000000000000000000000000000000000000000000000100000", + "blockHash": "0x2ba2274d8334e11975c51b3ec0bb574f93ac83042f9fd1863b28b6e183999f9d", + "transactionHash": "0x79bc48a59de268be4623c5a7a2e419da30b95b8bb7119f60e59f097c5aa30dba", + "logs": [ + { + "transactionIndex": 26, + "blockNumber": 62872232, + "transactionHash": "0x79bc48a59de268be4623c5a7a2e419da30b95b8bb7119f60e59f097c5aa30dba", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000b5ca125166c1987a35edd550e16846fa1e1d9bb3", + "0x00000000000000000000000083d69448f88bf9c701c1b93f43e1f753d39b2632" + ], + "data": "0x0000000000000000000000000000000000000000000000000032e47e5c4a2ad2000000000000000000000000000000000000000000000000344315f1bf0ff3a9000000000000000000000000000000000000000000000ba51a4e83ca9587c9510000000000000000000000000000000000000000000000003410317362c5c8d7000000000000000000000000000000000000000000000ba51a816848f1d1f423", + "logIndex": 91, + "blockHash": "0x2ba2274d8334e11975c51b3ec0bb574f93ac83042f9fd1863b28b6e183999f9d" + } + ], + "blockNumber": 62872232, + "cumulativeGasUsed": "3140534", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "4511b61209438ca20d2458493e70bb24", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/4511b61209438ca20d2458493e70bb24.json b/deployments/polygon/solcInputs/4511b61209438ca20d2458493e70bb24.json new file mode 100644 index 00000000..c068a9c4 --- /dev/null +++ b/deployments/polygon/solcInputs/4511b61209438ca20d2458493e70bb24.json @@ -0,0 +1,351 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/core/Module.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/governance/utils/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@prb/math/src/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" + }, + "@prb/math/src/sd1x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd1x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/sd1x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" + }, + "@prb/math/src/sd1x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" + }, + "@prb/math/src/sd59x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd59x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" + }, + "@prb/math/src/sd59x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" + }, + "@prb/math/src/sd59x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/sd59x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" + }, + "@prb/math/src/sd59x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" + }, + "@prb/math/src/UD2x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud2x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud2x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/ud2x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" + }, + "@prb/math/src/ud2x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" + }, + "@prb/math/src/UD60x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud60x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud60x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" + }, + "@prb/math/src/ud60x18/Conversions.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" + }, + "@prb/math/src/ud60x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" + }, + "@prb/math/src/ud60x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/ud60x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" + }, + "@prb/math/src/ud60x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" + }, + "contracts/DecentSablierStreamManagement.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/full/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/full/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/full/IAdminable.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" + }, + "contracts/interfaces/sablier/full/IERC4096.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2Lockup.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" + }, + "contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" + }, + "contracts/interfaces/sablier/full/types/DataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + }, + "contracts/mocks/ERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" + }, + "contracts/mocks/MockContract.sol": { + "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" + }, + "contracts/mocks/MockLockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file From 8dd38150ef6041c8c37cda26a12d1da240e03add Mon Sep 17 00:00:00 2001 From: Kellar Date: Thu, 10 Oct 2024 17:50:11 +0100 Subject: [PATCH 083/206] Bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b4f73ef..acf53bf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.14", + "version": "1.2.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.14", + "version": "1.2.15", "license": "MIT", "devDependencies": { "@gnosis.pm/zodiac": "^1.1.4", diff --git a/package.json b/package.json index de81f04e..44ccd3d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.14", + "version": "1.2.15", "files": [ "publish", "contracts", From 90c84119dea31e2864942084b7446c83ea96077b Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 10 Oct 2024 16:31:01 -0400 Subject: [PATCH 084/206] More comment out unused stuff --- deploy/core/011_deploy_ModuleProxyFactory.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/core/011_deploy_ModuleProxyFactory.ts b/deploy/core/011_deploy_ModuleProxyFactory.ts index 17873611..7d2b45e8 100644 --- a/deploy/core/011_deploy_ModuleProxyFactory.ts +++ b/deploy/core/011_deploy_ModuleProxyFactory.ts @@ -1,8 +1,8 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; +// import { HardhatRuntimeEnvironment } from "hardhat/types"; import { DeployFunction } from "hardhat-deploy/types"; // import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; -const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { +const func: DeployFunction = async (/* hre: HardhatRuntimeEnvironment */) => { // No longer deploying ModuleProxyFactory to any new networks.. // This contract is deployed by the Zodiac team. // await deployNonUpgradeable(hre, "ModuleProxyFactory", []); From b53e7c5de8f1d0244bae573a97d72abc9fe479e1 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 10 Oct 2024 16:42:49 -0400 Subject: [PATCH 085/206] Use a hardcoded and static "salt" for smart account creation --- contracts/DecentHats_0_1_0.sol | 16 +++------------- test/DecentHats_0_1_0.test.ts | 20 ++++---------------- test/helpers.ts | 6 ++---- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index c00dadaa..067ae470 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -44,19 +44,9 @@ contract DecentHats_0_1_0 { Hat[] hats; } - function getSalt() internal view returns (bytes32 salt) { - uint256 chainId; - assembly { - chainId := chainid() - } - - bytes memory concatenatedSaltInput = abi.encodePacked( - NAME, - chainId, - address(this) - ); - - salt = keccak256(concatenatedSaltInput); + function getSalt() internal pure returns (bytes32 salt) { + return + 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; } function updateKeyValuePairs( diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 0d42dc8e..ba38355d 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -19,20 +19,14 @@ import { import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; import { expect } from "chai"; -import { ethers, solidityPackedKeccak256 } from "ethers"; +import { ethers } from "ethers"; import hre from "hardhat"; import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory, } from "./GlobalSafeDeployments.test"; -import { - buildSafeTransaction, - buildSignatureBytes, - executeSafeTransaction, - predictGnosisSafeAddress, - safeSignTypedData, -} from "./helpers"; +import { executeSafeTransaction, predictGnosisSafeAddress } from "./helpers"; describe("DecentHats_0_1_0", () => { let dao: SignerWithAddress; @@ -285,14 +279,8 @@ describe("DecentHats_0_1_0", () => { }); describe("Creating Hats Accounts", () => { - let salt: string; - - beforeEach(async () => { - salt = solidityPackedKeccak256( - ["string", "uint256", "address"], - ["DecentHats_0_1_0", await hre.getChainId(), decentHatsAddress] - ); - }); + const salt = + "0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072"; const getHatAccount = async (hatId: bigint) => { const hatAccountAddress = await erc6551Registry.account( diff --git a/test/helpers.ts b/test/helpers.ts index c4a538f7..40055902 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -255,10 +255,8 @@ export const getHatAccount = async ( decentHatsAddress: string, signer: ethers.Signer ) => { - const salt = solidityPackedKeccak256( - ["string", "uint256", "address"], - ["DecentHats_0_1_0", await hre.getChainId(), decentHatsAddress] - ); + const salt = + "0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072"; const hatAccountAddress = await erc6551RegistryImplementation.account( mockHatsAccountImplementationAddress, From f1e6e92ef2252609d0d239f644463ca76f3200f4 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 10 Oct 2024 16:49:14 -0400 Subject: [PATCH 086/206] DRY up some duplicate code --- test/DecentHats_0_1_0.test.ts | 34 ++++++++-------------- test/DecentSablierStreamManagement.test.ts | 2 -- test/helpers.ts | 5 ++-- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index ba38355d..6c308a50 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -26,7 +26,11 @@ import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory, } from "./GlobalSafeDeployments.test"; -import { executeSafeTransaction, predictGnosisSafeAddress } from "./helpers"; +import { + executeSafeTransaction, + getHatAccount, + predictGnosisSafeAddress, +} from "./helpers"; describe("DecentHats_0_1_0", () => { let dao: SignerWithAddress; @@ -279,31 +283,17 @@ describe("DecentHats_0_1_0", () => { }); describe("Creating Hats Accounts", () => { - const salt = - "0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072"; - - const getHatAccount = async (hatId: bigint) => { - const hatAccountAddress = await erc6551Registry.account( - mockHatsAccountImplementationAddress, - salt, - await hre.getChainId(), - mockHatsAddress, - hatId - ); - - const hatAccount = MockHatsAccount__factory.connect( - hatAccountAddress, - hre.ethers.provider - ); - - return hatAccount; - }; - it("Generates the correct Addresses for the current Hats", async () => { const currentCount = await mockHats.count(); for (let i = 0n; i < currentCount; i++) { - const topHatAccount = await getHatAccount(i); + const topHatAccount = await getHatAccount( + i, + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress + ); + expect(await topHatAccount.tokenId()).eq(i); expect(await topHatAccount.tokenImplementation()).eq( mockHatsAddress diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 8e1b0ea5..227477c4 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -276,7 +276,6 @@ describe("DecentSablierStreamManagement", () => { erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, - decentHatsAddress, dao ); @@ -327,7 +326,6 @@ describe("DecentSablierStreamManagement", () => { erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, - decentHatsAddress, dao ); diff --git a/test/helpers.ts b/test/helpers.ts index 40055902..6c291701 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -252,8 +252,7 @@ export const getHatAccount = async ( erc6551RegistryImplementation: ERC6551Registry, mockHatsAccountImplementationAddress: string, mockHatsAddress: string, - decentHatsAddress: string, - signer: ethers.Signer + signer?: ethers.Signer ) => { const salt = "0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072"; @@ -268,7 +267,7 @@ export const getHatAccount = async ( const hatAccount = MockHatsAccount__factory.connect( hatAccountAddress, - signer + signer ?? hre.ethers.provider ); return hatAccount; From 0e7716fec9b255914b9f8494edd67d020d05e66a Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 10 Oct 2024 16:58:43 -0400 Subject: [PATCH 087/206] Make 'getSalt' function public --- contracts/DecentHats_0_1_0.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index 067ae470..a0d9a7bd 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -44,7 +44,7 @@ contract DecentHats_0_1_0 { Hat[] hats; } - function getSalt() internal pure returns (bytes32 salt) { + function getSalt() public pure returns (bytes32 salt) { return 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; } From 42c57e24e3dd071f7f3ec80e2fb8eaf84b490e68 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 10 Oct 2024 17:05:35 -0400 Subject: [PATCH 088/206] Deploy to all networks --- deployments/base/DecentHats_0_1_0.json | 41 ++++++++----- .../6ceb8d75a501322d052845dbe517017d.json | 59 +++++++++++++++++++ deployments/mainnet/DecentHats_0_1_0.json | 41 ++++++++----- .../6ceb8d75a501322d052845dbe517017d.json | 59 +++++++++++++++++++ deployments/optimism/DecentHats_0_1_0.json | 41 ++++++++----- .../6ceb8d75a501322d052845dbe517017d.json | 59 +++++++++++++++++++ deployments/polygon/DecentHats_0_1_0.json | 57 +++++++++++------- .../6ceb8d75a501322d052845dbe517017d.json | 59 +++++++++++++++++++ deployments/sepolia/DecentHats_0_1_0.json | 41 ++++++++----- .../6ceb8d75a501322d052845dbe517017d.json | 59 +++++++++++++++++++ 10 files changed, 438 insertions(+), 78 deletions(-) create mode 100644 deployments/base/solcInputs/6ceb8d75a501322d052845dbe517017d.json create mode 100644 deployments/mainnet/solcInputs/6ceb8d75a501322d052845dbe517017d.json create mode 100644 deployments/optimism/solcInputs/6ceb8d75a501322d052845dbe517017d.json create mode 100644 deployments/polygon/solcInputs/6ceb8d75a501322d052845dbe517017d.json create mode 100644 deployments/sepolia/solcInputs/6ceb8d75a501322d052845dbe517017d.json diff --git a/deployments/base/DecentHats_0_1_0.json b/deployments/base/DecentHats_0_1_0.json index 297f78a1..6ecfc1b4 100644 --- a/deployments/base/DecentHats_0_1_0.json +++ b/deployments/base/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0xfEFe8C7E647E66D1612Aea29f9A58172823473E0", + "address": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", "abi": [ { "inputs": [], @@ -274,30 +274,43 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [], + "name": "getSalt", + "outputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" } ], - "transactionHash": "0x1fc38c8f5da2e0e6b24a13b6799c8c5a9ec569034380afb572014941426742ce", + "transactionHash": "0x5d86a480602424ac02518917b0eb305225c80775da3569f318942c31ac8424b3", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xfEFe8C7E647E66D1612Aea29f9A58172823473E0", - "transactionIndex": 134, - "gasUsed": "1184549", + "contractAddress": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", + "transactionIndex": 56, + "gasUsed": "1162443", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x6b3e73c7394fc01da9e070b1f303a87428ed45c28fd33002d1aa8af5e90ded4f", - "transactionHash": "0x1fc38c8f5da2e0e6b24a13b6799c8c5a9ec569034380afb572014941426742ce", + "blockHash": "0x1eb0f75b3947cd2eacb086e5add97af2d11d11b47767445a9daf2cebc6589b07", + "transactionHash": "0x5d86a480602424ac02518917b0eb305225c80775da3569f318942c31ac8424b3", "logs": [], - "blockNumber": 19648644, - "cumulativeGasUsed": "19643187", + "blockNumber": 20902423, + "cumulativeGasUsed": "8359038", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "512807b5d71481c693c202ae23158904", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() internal view returns (bytes32 salt) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n bytes memory concatenatedSaltInput = abi.encodePacked(\\n NAME,\\n chainId,\\n address(this)\\n );\\n\\n salt = keccak256(concatenatedSaltInput);\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xdc0d2b3c556d675f26152895a17e1fb76c91d1a85b2689cf435fb3666381ac41\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611477806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "6ceb8d75a501322d052845dbe517017d", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/base/solcInputs/6ceb8d75a501322d052845dbe517017d.json b/deployments/base/solcInputs/6ceb8d75a501322d052845dbe517017d.json new file mode 100644 index 00000000..a59039b1 --- /dev/null +++ b/deployments/base/solcInputs/6ceb8d75a501322d052845dbe517017d.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function updateKeyValuePairs(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n updateKeyValuePairs(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/DecentHats_0_1_0.json b/deployments/mainnet/DecentHats_0_1_0.json index e702d8d6..616a515a 100644 --- a/deployments/mainnet/DecentHats_0_1_0.json +++ b/deployments/mainnet/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", + "address": "0x5843E6fa58163453A0A753a831E3BbdB2da06259", "abi": [ { "inputs": [], @@ -274,30 +274,43 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [], + "name": "getSalt", + "outputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" } ], - "transactionHash": "0xd64b5a21c53cd3281ea5a9384ffd4ecb357e8bb523f5127cc5822a662136db97", + "transactionHash": "0x45225faa4aac42f403a10912758bb375c1889ddf98627000370b20f840cc6365", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", - "transactionIndex": 145, - "gasUsed": "1184549", + "contractAddress": "0x5843E6fa58163453A0A753a831E3BbdB2da06259", + "transactionIndex": 38, + "gasUsed": "1162443", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdc359b7bbbca6bb854b228fef97081b90aaedb60ff522dcae7c148c7dec7d1f4", - "transactionHash": "0xd64b5a21c53cd3281ea5a9384ffd4ecb357e8bb523f5127cc5822a662136db97", + "blockHash": "0xc9ec4b47f2e757a387beeebfc3a17c51f90b4a81df75af0eab0d5286f5637cfe", + "transactionHash": "0x45225faa4aac42f403a10912758bb375c1889ddf98627000370b20f840cc6365", "logs": [], - "blockNumber": 20729758, - "cumulativeGasUsed": "13800573", + "blockNumber": 20937775, + "cumulativeGasUsed": "5113096", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "512807b5d71481c693c202ae23158904", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() internal view returns (bytes32 salt) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n bytes memory concatenatedSaltInput = abi.encodePacked(\\n NAME,\\n chainId,\\n address(this)\\n );\\n\\n salt = keccak256(concatenatedSaltInput);\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xdc0d2b3c556d675f26152895a17e1fb76c91d1a85b2689cf435fb3666381ac41\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611477806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "6ceb8d75a501322d052845dbe517017d", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/mainnet/solcInputs/6ceb8d75a501322d052845dbe517017d.json b/deployments/mainnet/solcInputs/6ceb8d75a501322d052845dbe517017d.json new file mode 100644 index 00000000..a59039b1 --- /dev/null +++ b/deployments/mainnet/solcInputs/6ceb8d75a501322d052845dbe517017d.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function updateKeyValuePairs(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n updateKeyValuePairs(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/DecentHats_0_1_0.json b/deployments/optimism/DecentHats_0_1_0.json index 8b6d7e5f..905e0851 100644 --- a/deployments/optimism/DecentHats_0_1_0.json +++ b/deployments/optimism/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0xfEFe8C7E647E66D1612Aea29f9A58172823473E0", + "address": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", "abi": [ { "inputs": [], @@ -274,30 +274,43 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [], + "name": "getSalt", + "outputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" } ], - "transactionHash": "0x2e4fa7b47997c07b811a519aed15ce4cd26a4ee4f653171df17b5b62177252d5", + "transactionHash": "0x838e49f34e0c5da270a3ee8945c11b664f1cc242cb6b3c794464795333813910", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xfEFe8C7E647E66D1612Aea29f9A58172823473E0", - "transactionIndex": 6, - "gasUsed": "1184549", + "contractAddress": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", + "transactionIndex": 12, + "gasUsed": "1162443", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x91e1a70dbf0793305c67cd6aed401ea9707a0429f7900dd0bb235e77e351d7b6", - "transactionHash": "0x2e4fa7b47997c07b811a519aed15ce4cd26a4ee4f653171df17b5b62177252d5", + "blockHash": "0x4673e4ee1835f9085310f9f34eb7da3086eba765920c7de3c35d4b6870f668c6", + "transactionHash": "0x838e49f34e0c5da270a3ee8945c11b664f1cc242cb6b3c794464795333813910", "logs": [], - "blockNumber": 125243972, - "cumulativeGasUsed": "2509623", + "blockNumber": 126497749, + "cumulativeGasUsed": "2827783", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "512807b5d71481c693c202ae23158904", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() internal view returns (bytes32 salt) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n bytes memory concatenatedSaltInput = abi.encodePacked(\\n NAME,\\n chainId,\\n address(this)\\n );\\n\\n salt = keccak256(concatenatedSaltInput);\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xdc0d2b3c556d675f26152895a17e1fb76c91d1a85b2689cf435fb3666381ac41\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611477806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "6ceb8d75a501322d052845dbe517017d", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/optimism/solcInputs/6ceb8d75a501322d052845dbe517017d.json b/deployments/optimism/solcInputs/6ceb8d75a501322d052845dbe517017d.json new file mode 100644 index 00000000..a59039b1 --- /dev/null +++ b/deployments/optimism/solcInputs/6ceb8d75a501322d052845dbe517017d.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function updateKeyValuePairs(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n updateKeyValuePairs(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/DecentHats_0_1_0.json b/deployments/polygon/DecentHats_0_1_0.json index c61a33d3..430c2ee9 100644 --- a/deployments/polygon/DecentHats_0_1_0.json +++ b/deployments/polygon/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0xFe376AAD5bB1c3Ce27fb27Ece130F7B0ba8D9642", + "address": "0xF45EAc866BAD509B0CD233869b61be8b0BC6dBd8", "abi": [ { "inputs": [], @@ -274,46 +274,59 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [], + "name": "getSalt", + "outputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" } ], - "transactionHash": "0x8c847e6203727e72edd6e26fd766f001b00b4f376b8b5d213747c4810b88f0aa", + "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xFe376AAD5bB1c3Ce27fb27Ece130F7B0ba8D9642", - "transactionIndex": 21, - "gasUsed": "1184549", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000008000000000000000000000000000000080000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000080000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000100004000000000000000000200000000000000000000000000000000000000000000000100000", - "blockHash": "0x45cf379015e0b94be073160f13083eca51f6ae16633be5a9b0061bc8d582fea6", - "transactionHash": "0x8c847e6203727e72edd6e26fd766f001b00b4f376b8b5d213747c4810b88f0aa", + "contractAddress": "0xF45EAc866BAD509B0CD233869b61be8b0BC6dBd8", + "transactionIndex": 9, + "gasUsed": "1162443", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000100004000000000000000000200000000000000000000000000000000000000000000000100000", + "blockHash": "0x7d22d6e543e1e0df7018ad856b6b90ec9d58b64b8b0ffc66abc8ad4d4c2ac537", + "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", "logs": [ { - "transactionIndex": 21, - "blockNumber": 61707503, - "transactionHash": "0x8c847e6203727e72edd6e26fd766f001b00b4f376b8b5d213747c4810b88f0aa", + "transactionIndex": 9, + "blockNumber": 62879901, + "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x000000000000000000000000b5ca125166c1987a35edd550e16846fa1e1d9bb3", - "0x000000000000000000000000f0245f6251bef9447a08766b9da2b07b28ad80b0" + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" ], - "data": "0x00000000000000000000000000000000000000000000000000bd6058c704764d0000000000000000000000000000000000000000000000003500764a878ffbff0000000000000000000000000000000000000000000007c594b667ebb781d267000000000000000000000000000000000000000000000000344315f1c08b85b20000000000000000000000000000000000000000000007c59573c8447e8648b4", - "logIndex": 74, - "blockHash": "0x45cf379015e0b94be073160f13083eca51f6ae16633be5a9b0061bc8d582fea6" + "data": "0x00000000000000000000000000000000000000000000000001084f16858b800000000000000000000000000000000000000000000000000034103173616baf340000000000000000000000000000000000000000000339407dbafe9f1de83cf40000000000000000000000000000000000000000000000003307e25cdbe02f340000000000000000000000000000000000000000000339407ec34db5a373bcf4", + "logIndex": 91, + "blockHash": "0x7d22d6e543e1e0df7018ad856b6b90ec9d58b64b8b0ffc66abc8ad4d4c2ac537" } ], - "blockNumber": 61707503, - "cumulativeGasUsed": "3780485", + "blockNumber": 62879901, + "cumulativeGasUsed": "3502682", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 2, - "solcInputHash": "512807b5d71481c693c202ae23158904", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() internal view returns (bytes32 salt) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n bytes memory concatenatedSaltInput = abi.encodePacked(\\n NAME,\\n chainId,\\n address(this)\\n );\\n\\n salt = keccak256(concatenatedSaltInput);\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xdc0d2b3c556d675f26152895a17e1fb76c91d1a85b2689cf435fb3666381ac41\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611477806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", + "numDeployments": 3, + "solcInputHash": "6ceb8d75a501322d052845dbe517017d", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/polygon/solcInputs/6ceb8d75a501322d052845dbe517017d.json b/deployments/polygon/solcInputs/6ceb8d75a501322d052845dbe517017d.json new file mode 100644 index 00000000..a59039b1 --- /dev/null +++ b/deployments/polygon/solcInputs/6ceb8d75a501322d052845dbe517017d.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function updateKeyValuePairs(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n updateKeyValuePairs(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/sepolia/DecentHats_0_1_0.json b/deployments/sepolia/DecentHats_0_1_0.json index e60e4085..d0d70862 100644 --- a/deployments/sepolia/DecentHats_0_1_0.json +++ b/deployments/sepolia/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x8250B3b8BcD854750B0ACdEE7298C6626D6ba9b9", + "address": "0x577FcfB0655f24809345E951f188b1929A961E42", "abi": [ { "inputs": [], @@ -274,30 +274,43 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [], + "name": "getSalt", + "outputs": [ + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" } ], - "transactionHash": "0x42be72ca7992fefb68ef43f7e03262d9592787b97513170a23fa0093c49caff1", + "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", "receipt": { "to": null, "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x8250B3b8BcD854750B0ACdEE7298C6626D6ba9b9", - "transactionIndex": 71, - "gasUsed": "1184549", + "contractAddress": "0x577FcfB0655f24809345E951f188b1929A961E42", + "transactionIndex": 9, + "gasUsed": "1162443", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x51126bdfcd86505547307e84c6b9a3b13376d1b3e481f1a70a72465283983f5d", - "transactionHash": "0x42be72ca7992fefb68ef43f7e03262d9592787b97513170a23fa0093c49caff1", + "blockHash": "0x614020dff98bee6b1b1949ba946f7f8d5b1054f3199eb499f979e82889712945", + "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", "logs": [], - "blockNumber": 6673787, - "cumulativeGasUsed": "8858403", + "blockNumber": 6852403, + "cumulativeGasUsed": "1938170", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 4, - "solcInputHash": "512807b5d71481c693c202ae23158904", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() internal view returns (bytes32 salt) {\\n uint256 chainId;\\n assembly {\\n chainId := chainid()\\n }\\n\\n bytes memory concatenatedSaltInput = abi.encodePacked(\\n NAME,\\n chainId,\\n address(this)\\n );\\n\\n salt = keccak256(concatenatedSaltInput);\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xdc0d2b3c556d675f26152895a17e1fb76c91d1a85b2689cf435fb3666381ac41\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611477806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80638c5f591a1461003b578063a3f4df7e14610050575b600080fd5b61004e610049366004610ac2565b610095565b005b61007f6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161008c9190610b54565b60405180910390f35b600061009f6102cd565b905060008061015e6100b46020860186610b7f565b6100c16080870187610b9c565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506101039250505060a0880188610b9c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610148925050506060890160408a01610b7f565b61015860408a0160208b01610b7f565b88610331565b909250905061017c6101766080860160608701610b7f565b836103c3565b60006101c361018e6020870187610b7f565b8461019c60c0890189610bf9565b856101ad60608b0160408c01610b7f565b6101bd60408c0160208d01610b7f565b8a610543565b50905060005b6101d660e0870187610c19565b9050811015610250576102466101ef6020880188610b7f565b836101fd60e08a018a610c19565b8581811061020d5761020d610c62565b905060200281019061021f9190610bf9565b8661023060608c0160408d01610b7f565b61024060408d0160208e01610b7f565b8b610543565b50506001016101c9565b5061025e6020860186610b7f565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102ae57600080fd5b505af11580156102c2573d6000803e3d6000fd5b505050505050505050565b60008046905060006040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b815250823060405160200161031293929190610c78565b60408051601f1981840301815291905280516020909101209392505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161036493929190610cb1565b6020604051808303816000875af1158015610383573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103a79190610ce7565b91506103b68585858b86610892565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103da57505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610409579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061045457610454610c62565b602002602001018190525061046883610928565b8160008151811061047b5761047b610c62565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016104ab929190610d6b565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104f993929190600090600401610d90565b6020604051808303816000875af1158015610518573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061053c9190610df4565b5050505050565b60008061055a89896105548a61113b565b89610a30565b91506105698585858c86610892565b9050600061057d60a0890160808a01610b7f565b6001600160a01b03161461061d576001600160a01b03891663641f776e836105ab60a08b0160808c01610b7f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061b9190610df4565b505b60005b61062d60a08901896111ff565b905081101561088557600061064560a08a018a6111ff565b8381811061065557610655610c62565b9050610160020180360381019061066c9190611248565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106f993929190600090600401610d90565b6020604051808303816000875af1158015610718573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073c9190610df4565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107e69190611265565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261083493929190600090600401610d90565b6020604051808303816000875af1158015610853573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108779190610df4565b508260010192505050610620565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061091e9190611327565b9695505050505050565b60608160000361094f5750506040805180820190915260018152600360fc1b602082015290565b8160005b811561097957806109638161135a565b91506109729050600a83611389565b9150610953565b6000816001600160401b0381111561099357610993610d00565b6040519080825280601f01601f1916602001820160405280156109bd576020820181803683370190505b5090505b8415610a28576109d260018361139d565b91506109df600a866113b6565b6109ea9060306113ca565b60f81b8183815181106109ff576109ff610c62565b60200101906001600160f81b031916908160001a905350610a21600a86611389565b94506109c1565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a76948b948a92839290916004016113dd565b6020604051808303816000875af1158015610a95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab99190610ce7565b95945050505050565b600060208284031215610ad457600080fd5b81356001600160401b03811115610aea57600080fd5b82016101008185031215610afd57600080fd5b9392505050565b60005b83811015610b1f578181015183820152602001610b07565b50506000910152565b60008151808452610b40816020860160208601610b04565b601f01601f19169290920160200192915050565b602081526000610afd6020830184610b28565b6001600160a01b0381168114610b7c57600080fd5b50565b600060208284031215610b9157600080fd5b8135610afd81610b67565b6000808335601e19843603018112610bb357600080fd5b8301803591506001600160401b03821115610bcd57600080fd5b602001915036819003821315610be257600080fd5b9250929050565b8035610bf481610b67565b919050565b6000823560be19833603018112610c0f57600080fd5b9190910192915050565b6000808335601e19843603018112610c3057600080fd5b8301803591506001600160401b03821115610c4a57600080fd5b6020019150600581901b3603821315610be257600080fd5b634e487b7160e01b600052603260045260246000fd5b60008451610c8a818460208901610b04565b919091019283525060601b6bffffffffffffffffffffffff19166020820152603401919050565b6001600160a01b0384168152606060208201819052600090610cd590830185610b28565b828103604084015261091e8185610b28565b600060208284031215610cf957600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501808196508360051b8101915082860160005b85811015610d5e578284038952610d4c848351610b28565b98850198935090840190600101610d34565b5091979650505050505050565b604081526000610d7e6040830185610d16565b8281036020840152610ab98185610d16565b60018060a01b0385168152836020820152608060408201526000610db76080830185610b28565b905060028310610dd757634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b7c57600080fd5b600060208284031215610e0657600080fd5b8151610afd81610de6565b60405160c081016001600160401b0381118282101715610e3357610e33610d00565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e6157610e61610d00565b604052919050565b803563ffffffff81168114610bf457600080fd5b600082601f830112610e8e57600080fd5b81356001600160401b03811115610ea757610ea7610d00565b610eba601f8201601f1916602001610e39565b818152846020838601011115610ecf57600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bf481610de6565b80356001600160801b0381168114610bf457600080fd5b803564ffffffffff81168114610bf457600080fd5b600060608284031215610f3557600080fd5b604051606081018181106001600160401b0382111715610f5757610f57610d00565b604052905080610f6683610f0e565b8152610f7460208401610f0e565b6020820152610f8560408401610f0e565b60408201525092915050565b600060408284031215610fa357600080fd5b604051604081018181106001600160401b0382111715610fc557610fc5610d00565b6040529050808235610fd681610b67565b8152602092830135920191909152919050565b60006101608284031215610ffc57600080fd5b60405161010081018181106001600160401b038211171561101f5761101f610d00565b60405290508061102e83610be9565b815261103c60208401610be9565b602082015261104d60408401610ef7565b604082015261105e60608401610be9565b606082015261106f60808401610eec565b608082015261108060a08401610eec565b60a08201526110928460c08501610f23565b60c08201526110a5846101208501610f91565b60e08201525092915050565b600082601f8301126110c257600080fd5b813560206001600160401b038211156110dd576110dd610d00565b6110eb818360051b01610e39565b828152610160928302850182019282820191908785111561110b57600080fd5b8387015b8581101561112e576111218982610fe9565b845292840192810161110f565b5090979650505050505050565b600060c0823603121561114d57600080fd5b611155610e11565b61115e83610e69565b815260208301356001600160401b038082111561117a57600080fd5b61118636838701610e7d565b6020840152604085013591508082111561119f57600080fd5b6111ab36838701610e7d565b60408401526111bc60608601610eec565b60608401526111cd60808601610be9565b608084015260a08501359150808211156111e657600080fd5b506111f3368286016110b1565b60a08301525092915050565b6000808335601e1984360301811261121657600080fd5b8301803591506001600160401b0382111561123057600080fd5b602001915061016081023603821315610be257600080fd5b6000610160828403121561125b57600080fd5b610afd8383610fe9565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112b99084018215159052565b5060a08301516112cd60a084018215159052565b5060c083015161130060c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b60006020828403121561133957600080fd5b8151610afd81610b67565b634e487b7160e01b600052601160045260246000fd5b60006001820161136c5761136c611344565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261139857611398611373565b500490565b818103818111156113b0576113b0611344565b92915050565b6000826113c5576113c5611373565b500690565b808201808211156113b0576113b0611344565b87815260e0602082015260006113f660e0830189610b28565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114338185610b28565b9a995050505050505050505056fea2646970667358221220d17954ba81bca52da6ca1f1cf74a0e04f2ce3c50651d1d806611eb18ab0d551e64736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "6ceb8d75a501322d052845dbe517017d", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/sepolia/solcInputs/6ceb8d75a501322d052845dbe517017d.json b/deployments/sepolia/solcInputs/6ceb8d75a501322d052845dbe517017d.json new file mode 100644 index 00000000..a59039b1 --- /dev/null +++ b/deployments/sepolia/solcInputs/6ceb8d75a501322d052845dbe517017d.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function updateKeyValuePairs(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n updateKeyValuePairs(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file From e1b43d55ec1fe6aa6f93ab8bdc7790b219b3b7ac Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 10 Oct 2024 17:05:55 -0400 Subject: [PATCH 089/206] Bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index acf53bf0..7aa16857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.15", + "version": "1.2.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.15", + "version": "1.2.16", "license": "MIT", "devDependencies": { "@gnosis.pm/zodiac": "^1.1.4", diff --git a/package.json b/package.json index 44ccd3d4..7a7fce94 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.15", + "version": "1.2.16", "files": [ "publish", "contracts", From d0a6e044016bbf82cff15123253843b97e8a9ed6 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:30:54 -0400 Subject: [PATCH 090/206] renaming and move salt to constant --- .../{DecentHats_0_2_0.sol => DecentHats.sol} | 62 +++++-------------- deploy/core/011_deploy_ModuleProxyFactory.ts | 2 +- deploy/core/017_deploy_DecentHats_0_1_0.ts | 16 ++--- ...Hats_0_2_0.ts => 018_deploy_DecentHats.ts} | 2 +- ...tHats_0_2_0.test.ts => DecentHats.test.ts} | 32 +++++----- 5 files changed, 45 insertions(+), 69 deletions(-) rename contracts/{DecentHats_0_2_0.sol => DecentHats.sol} (88%) rename deploy/core/{018_deploy_DecentHats_0_2_0.ts => 018_deploy_DecentHats.ts} (83%) rename test/{DecentHats_0_2_0.test.ts => DecentHats.test.ts} (95%) diff --git a/contracts/DecentHats_0_2_0.sol b/contracts/DecentHats.sol similarity index 88% rename from contracts/DecentHats_0_2_0.sol rename to contracts/DecentHats.sol index 29160a68..7009d80e 100644 --- a/contracts/DecentHats_0_2_0.sol +++ b/contracts/DecentHats.sol @@ -13,8 +13,9 @@ import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol" import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; -contract DecentHats_0_2_0 { - string public constant NAME = "DecentHats_0_2_0"; +contract DecentHats { + string public constant NAME = "DecentHats"; + bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; struct SablierStreamParams { address sablierV2LockupLinear; @@ -56,21 +57,20 @@ contract DecentHats_0_2_0 { Hat[] hats; string topHatDetails; string topHatImageURI; + } /* ///////////////////////////////////////////////////////////////////////////// EXTERNAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ function createAndDeclareTree(CreateTreeParams calldata params) public { - bytes32 salt = _getSalt(); (uint256 topHatId, address topHatAccount) = _createTopHatAndAccount( params.hatsProtocol, params.topHatDetails, params.topHatImageURI, params.registry, - params.hatsAccountImplementation, - salt + params.hatsAccountImplementation ); _updateKeyValuePairs(params.keyValuePairs, topHatId); @@ -83,8 +83,7 @@ contract DecentHats_0_2_0 { params.hatsAccountImplementation, topHatAccount, topHatId, - params.adminHat, - salt + params.adminHat ); for (uint256 i = 0; i < params.hats.length; ) { @@ -94,8 +93,7 @@ contract DecentHats_0_2_0 { topHatAccount, params.hatsAccountImplementation, adminHatId, - params.hats[i], - salt + params.hats[i] ); if (params.hats[i].isTermed) { @@ -106,8 +104,7 @@ contract DecentHats_0_2_0 { params.hatsElectionEligibilityImplementation, hatId, topHatId, - params.hats[i].termedParams[0], - uint256(keccak256(abi.encode(salt, hatId))) + params.hats[i].termedParams[0] ); } @@ -123,31 +120,14 @@ contract DecentHats_0_2_0 { INTERAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ - function _getSalt() internal view returns (bytes32 salt) { - uint256 chainId; - assembly { - chainId := chainid() - } - - bytes memory concatenatedSaltInput = abi.encodePacked( - NAME, - chainId, - address(this) - ); - - salt = keccak256(concatenatedSaltInput); - } - function _updateKeyValuePairs( address _keyValuePairs, uint256 topHatId ) internal { - string[] memory keys = new string[](2); - string[] memory values = new string[](2); + string[] memory keys = new string[](1); + string[] memory values = new string[](1); keys[0] = "topHatId"; values[0] = Strings.toString(topHatId); - keys[1] = "decentHatsAddress"; - values[1] = Strings.toHexString(address(this)); IAvatar(msg.sender).execTransactionFromModule( _keyValuePairs, @@ -182,14 +162,13 @@ contract DecentHats_0_2_0 { function _createAccount( IERC6551Registry _registry, address _hatsAccountImplementation, - bytes32 salt, address protocolAddress, uint256 hatId ) internal returns (address) { return _registry.createAccount( _hatsAccountImplementation, - salt, + SALT, block.chainid, protocolAddress, hatId @@ -201,8 +180,7 @@ contract DecentHats_0_2_0 { string memory _topHatDetails, string memory _topHatImageURI, IERC6551Registry _registry, - address _hatsAccountImplementation, - bytes32 salt + address _hatsAccountImplementation ) internal returns (uint256 topHatId, address topHatAccount) { topHatId = _hatsProtocol.mintTopHat( address(this), @@ -213,7 +191,6 @@ contract DecentHats_0_2_0 { topHatAccount = _createAccount( _registry, _hatsAccountImplementation, - salt, address(_hatsProtocol), topHatId ); @@ -225,15 +202,13 @@ contract DecentHats_0_2_0 { address topHatAccount, address hatsAccountImplementation, uint256 adminHatId, - Hat calldata hat, - bytes32 salt + Hat calldata hat ) internal returns (uint256 hatId, address accountAddress) { hatId = _createHat(hatsProtocol, adminHatId, hat, topHatAccount); accountAddress = _createAccount( registry, hatsAccountImplementation, - salt, address(hatsProtocol), hatId ); @@ -293,15 +268,13 @@ contract DecentHats_0_2_0 { address hatsAccountImplementation, address topHatAccount, uint256 topHatId, - Hat calldata hat, - bytes32 salt + Hat calldata hat ) internal returns (uint256 adminHatId, address accountAddress) { adminHatId = _createHat(hatsProtocol, topHatId, hat, topHatAccount); accountAddress = _createAccount( registry, hatsAccountImplementation, - salt, address(hatsProtocol), adminHatId ); @@ -311,7 +284,7 @@ contract DecentHats_0_2_0 { moduleProxyFactory.deployModule( decentAutonomousAdminMasterCopy, abi.encodeWithSignature("setUp()"), - uint256(keccak256(abi.encodePacked(salt, adminHatId))) + uint256(keccak256(abi.encodePacked(SALT, adminHatId))) ) ); } @@ -330,15 +303,14 @@ contract DecentHats_0_2_0 { address hatsElectionEligibilityImplementation, uint256 hatId, uint256 topHatId, - TermedParams calldata termedParams, - uint256 saltNonce + TermedParams calldata termedParams ) internal returns (address) { address electionModuleAddress = hatsModuleFactory.createHatsModule( hatsElectionEligibilityImplementation, hatId, abi.encode(topHatId, uint256(0)), abi.encode(termedParams.termEndDateTs), - saltNonce + uint256(SALT) ); hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); diff --git a/deploy/core/011_deploy_ModuleProxyFactory.ts b/deploy/core/011_deploy_ModuleProxyFactory.ts index 17873611..15494c3a 100644 --- a/deploy/core/011_deploy_ModuleProxyFactory.ts +++ b/deploy/core/011_deploy_ModuleProxyFactory.ts @@ -2,7 +2,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"; import { DeployFunction } from "hardhat-deploy/types"; // import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; -const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { +const func: DeployFunction = async (_: HardhatRuntimeEnvironment) => { // No longer deploying ModuleProxyFactory to any new networks.. // This contract is deployed by the Zodiac team. // await deployNonUpgradeable(hre, "ModuleProxyFactory", []); diff --git a/deploy/core/017_deploy_DecentHats_0_1_0.ts b/deploy/core/017_deploy_DecentHats_0_1_0.ts index 6272efd1..3b66e607 100644 --- a/deploy/core/017_deploy_DecentHats_0_1_0.ts +++ b/deploy/core/017_deploy_DecentHats_0_1_0.ts @@ -1,9 +1,11 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from "hardhat/types" +import { DeployFunction } from "hardhat-deploy/types" +// import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; -const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentHats_0_1_0"); -}; +const func: DeployFunction = async (_: HardhatRuntimeEnvironment) => { + // No longer deploying DecentHats_0_1_0 to any new networks.. + // This contract has been depreciated. + // await deployNonUpgradeable(hre, "DecentHats_0_1_0"); +} -export default func; +export default func diff --git a/deploy/core/018_deploy_DecentHats_0_2_0.ts b/deploy/core/018_deploy_DecentHats.ts similarity index 83% rename from deploy/core/018_deploy_DecentHats_0_2_0.ts rename to deploy/core/018_deploy_DecentHats.ts index 66da759a..a372d413 100644 --- a/deploy/core/018_deploy_DecentHats_0_2_0.ts +++ b/deploy/core/018_deploy_DecentHats.ts @@ -3,7 +3,7 @@ import { DeployFunction } from "hardhat-deploy/types"; import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentHats_0_2_0"); + await deployNonUpgradeable(hre, "DecentHats"); }; export default func; diff --git a/test/DecentHats_0_2_0.test.ts b/test/DecentHats.test.ts similarity index 95% rename from test/DecentHats_0_2_0.test.ts rename to test/DecentHats.test.ts index 0014cc33..a88ef950 100644 --- a/test/DecentHats_0_2_0.test.ts +++ b/test/DecentHats.test.ts @@ -1,14 +1,14 @@ import { GnosisSafeL2, GnosisSafeL2__factory, - DecentHats_0_2_0__factory, + DecentHats__factory, KeyValuePairs, KeyValuePairs__factory, MockHats__factory, ERC6551Registry__factory, MockHatsAccount__factory, ERC6551Registry, - DecentHats_0_2_0, + DecentHats, MockHatsAccount, MockHats, MockSablierV2LockupLinear__factory, @@ -25,7 +25,7 @@ import { import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" import { expect } from "chai" -import { ethers, solidityPackedKeccak256 } from "ethers" +import { ethers, keccak256, solidityPackedKeccak256, toUtf8Bytes } from "ethers" import hre from "hardhat" import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test" @@ -73,7 +73,7 @@ const executeSafeTransaction = async ({ return tx } -describe("DecentHats_0_2_0", () => { +describe.only("DecentHats", () => { let dao: SignerWithAddress let mockHats: MockHats @@ -82,7 +82,7 @@ describe("DecentHats_0_2_0", () => { let keyValuePairs: KeyValuePairs let gnosisSafe: GnosisSafeL2 - let decentHats: DecentHats_0_2_0 + let decentHats: DecentHats let decentHatsAddress: string let gnosisSafeAddress: string @@ -120,7 +120,7 @@ describe("DecentHats_0_2_0", () => { erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress() - decentHats = await new DecentHats_0_2_0__factory(deployer).deploy() + decentHats = await new DecentHats__factory(deployer).deploy() decentHatsAddress = await decentHats.getAddress() moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() @@ -202,7 +202,7 @@ describe("DecentHats_0_2_0", () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + transactionData: DecentHats__factory.createInterface().encodeFunctionData( "createAndDeclareTree", [ { @@ -264,6 +264,7 @@ describe("DecentHats_0_2_0", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + pepper: keccak256(toUtf8Bytes("pepper")), }, ] ), @@ -294,7 +295,7 @@ describe("DecentHats_0_2_0", () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + transactionData: DecentHats__factory.createInterface().encodeFunctionData( "createAndDeclareTree", [ { @@ -304,7 +305,8 @@ describe("DecentHats_0_2_0", () => { keyValuePairs: await keyValuePairs.getAddress(), topHatDetails: "", topHatImageURI: "", - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminMasterCopy: + await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, @@ -325,6 +327,7 @@ describe("DecentHats_0_2_0", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + pepper: keccak256(toUtf8Bytes("pepper")), }, ] ), @@ -353,10 +356,7 @@ describe("DecentHats_0_2_0", () => { let salt: string beforeEach(async () => { - salt = solidityPackedKeccak256( - ["string", "uint256", "address"], - ["DecentHats_0_2_0", await hre.getChainId(), decentHatsAddress] - ) + salt = keccak256(toUtf8Bytes("pepper")) }) const getHatAccount = async (hatId: bigint) => { @@ -398,7 +398,7 @@ describe("DecentHats_0_2_0", () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + transactionData: DecentHats__factory.createInterface().encodeFunctionData( "createAndDeclareTree", [ { @@ -475,6 +475,7 @@ describe("DecentHats_0_2_0", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + pepper: keccak256(toUtf8Bytes("pepper")), }, ] ), @@ -540,7 +541,7 @@ describe("DecentHats_0_2_0", () => { await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_2_0__factory.createInterface().encodeFunctionData( + transactionData: DecentHats__factory.createInterface().encodeFunctionData( "createAndDeclareTree", [ { @@ -616,6 +617,7 @@ describe("DecentHats_0_2_0", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, + pepper: keccak256(toUtf8Bytes("pepper")), }, ] ), From 58c34688cc8f02017020c6c16af9aa71a7ed0554 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:35:58 -0400 Subject: [PATCH 091/206] update tests to read SALT from contract --- test/DecentHats.test.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index a88ef950..22a361d9 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -73,7 +73,7 @@ const executeSafeTransaction = async ({ return tx } -describe.only("DecentHats", () => { +describe("DecentHats", () => { let dao: SignerWithAddress let mockHats: MockHats @@ -264,7 +264,6 @@ describe.only("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - pepper: keccak256(toUtf8Bytes("pepper")), }, ] ), @@ -327,7 +326,7 @@ describe.only("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - pepper: keccak256(toUtf8Bytes("pepper")), + }, ] ), @@ -356,7 +355,7 @@ describe.only("DecentHats", () => { let salt: string beforeEach(async () => { - salt = keccak256(toUtf8Bytes("pepper")) + salt = await decentHats.SALT() }) const getHatAccount = async (hatId: bigint) => { @@ -475,7 +474,7 @@ describe.only("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - pepper: keccak256(toUtf8Bytes("pepper")), + }, ] ), @@ -617,7 +616,7 @@ describe.only("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - pepper: keccak256(toUtf8Bytes("pepper")), + }, ] ), From bdd2678e1b62beba30de67af85bf261b0bea7c42 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Fri, 11 Oct 2024 03:03:01 -0400 Subject: [PATCH 092/206] reorder new deploy scripts --- .../core/{018_deploy_DecentHats.ts => 019_deploy_DecentHats.ts} | 0 ...centAutonomousAdmin.ts => 020_deploy_DecentAutonomousAdmin.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename deploy/core/{018_deploy_DecentHats.ts => 019_deploy_DecentHats.ts} (100%) rename deploy/core/{019_deploy_DecentAutonomousAdmin.ts => 020_deploy_DecentAutonomousAdmin.ts} (100%) diff --git a/deploy/core/018_deploy_DecentHats.ts b/deploy/core/019_deploy_DecentHats.ts similarity index 100% rename from deploy/core/018_deploy_DecentHats.ts rename to deploy/core/019_deploy_DecentHats.ts diff --git a/deploy/core/019_deploy_DecentAutonomousAdmin.ts b/deploy/core/020_deploy_DecentAutonomousAdmin.ts similarity index 100% rename from deploy/core/019_deploy_DecentAutonomousAdmin.ts rename to deploy/core/020_deploy_DecentAutonomousAdmin.ts From a05a74ba4ef7915d919f2d30676abacdd5ecc7fa Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 12 Oct 2024 13:32:44 -0400 Subject: [PATCH 093/206] revert changes made to struct --- contracts/DecentHats.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 7009d80e..3d4dd4bf 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -12,13 +12,15 @@ import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; +import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; contract DecentHats { string public constant NAME = "DecentHats"; - bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; + bytes32 public constant SALT = + 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; struct SablierStreamParams { - address sablierV2LockupLinear; + ISablierV2LockupLinear sablier; address sender; address asset; LockupLinear.Timestamps timestamps; @@ -57,14 +59,12 @@ contract DecentHats { Hat[] hats; string topHatDetails; string topHatImageURI; - } /* ///////////////////////////////////////////////////////////////////////////// EXTERNAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ function createAndDeclareTree(CreateTreeParams calldata params) public { - (uint256 topHatId, address topHatAccount) = _createTopHatAndAccount( params.hatsProtocol, params.topHatDetails, @@ -225,7 +225,7 @@ contract DecentHats { 0, abi.encodeWithSignature( "approve(address,uint256)", - sablierParams.sablierV2LockupLinear, + sablierParams.sablier, sablierParams.totalAmount ), Enum.Operation.Call @@ -245,7 +245,7 @@ contract DecentHats { // Proxy the Sablier call through IAvatar IAvatar(msg.sender).execTransactionFromModule( - sablierParams.sablierV2LockupLinear, + address(sablierParams.sablier), 0, abi.encodeWithSignature( "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", From cc595bd7bf497cc224ea133bd6a8ec3a10db4dc1 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:54:54 -0400 Subject: [PATCH 094/206] set eligibility module and elect when new term role --- contracts/DecentHats.sol | 69 ++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 3d4dd4bf..952ff5e3 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -87,24 +87,32 @@ contract DecentHats { ); for (uint256 i = 0; i < params.hats.length; ) { - (uint256 hatId, ) = _createHatAndAccountAndMintAndStreams( + address eligibilityAddress = topHatAccount; + if (params.hats[i].isTermed) { + uint256 hatId = params.hatsProtocol.getNextId(adminHatId); + // Create election module and set as eligiblity, elect, and start next term + eligibilityAddress = _createElectionModule( + params.hatsModuleFactory, + params.hatsElectionEligibilityImplementation, + hatId, + topHatId, + params.hats[i].termedParams[0] + ); + } + _createHatAndAccountAndMintAndStreams( params.hatsProtocol, params.registry, topHatAccount, params.hatsAccountImplementation, adminHatId, - params.hats[i] + params.hats[i], + eligibilityAddress ); if (params.hats[i].isTermed) { - // Create election module and set as eligiblity, elect, and start next term - _createElectionModuleAndExecuteFirstTerm( - params.hatsProtocol, - params.hatsModuleFactory, - params.hatsElectionEligibilityImplementation, - hatId, - topHatId, - params.hats[i].termedParams[0] + IHatsElectionEligibility(eligibilityAddress).elect( + params.hats[i].termedParams[0].termEndDateTs, + params.hats[i].termedParams[0].nominatedWearers ); } @@ -145,15 +153,16 @@ contract DecentHats { IHats _hatsProtocol, uint256 adminHatId, Hat memory _hat, - address topHatAccount + address toggle, + address eligibility ) internal returns (uint256) { return _hatsProtocol.createHat( adminHatId, _hat.details, _hat.maxSupply, - topHatAccount, - topHatAccount, + eligibility, + toggle, _hat.isMutable, _hat.imageURI ); @@ -202,9 +211,16 @@ contract DecentHats { address topHatAccount, address hatsAccountImplementation, uint256 adminHatId, - Hat calldata hat + Hat calldata hat, + address eligibilityAddress ) internal returns (uint256 hatId, address accountAddress) { - hatId = _createHat(hatsProtocol, adminHatId, hat, topHatAccount); + hatId = _createHat( + hatsProtocol, + adminHatId, + hat, + topHatAccount, + eligibilityAddress + ); accountAddress = _createAccount( registry, @@ -270,7 +286,13 @@ contract DecentHats { uint256 topHatId, Hat calldata hat ) internal returns (uint256 adminHatId, address accountAddress) { - adminHatId = _createHat(hatsProtocol, topHatId, hat, topHatAccount); + adminHatId = _createHat( + hatsProtocol, + topHatId, + hat, + topHatAccount, + topHatAccount + ); accountAddress = _createAccount( registry, @@ -297,28 +319,19 @@ contract DecentHats { return abi.encodePacked(bytecode, constructorArgs); } - function _createElectionModuleAndExecuteFirstTerm( - IHats hatsProtocol, + function _createElectionModule( IHatsModuleFactory hatsModuleFactory, address hatsElectionEligibilityImplementation, uint256 hatId, uint256 topHatId, TermedParams calldata termedParams - ) internal returns (address) { - address electionModuleAddress = hatsModuleFactory.createHatsModule( + ) internal returns (address electionModuleAddress) { + electionModuleAddress = hatsModuleFactory.createHatsModule( hatsElectionEligibilityImplementation, hatId, abi.encode(topHatId, uint256(0)), abi.encode(termedParams.termEndDateTs), uint256(SALT) ); - hatsProtocol.changeHatEligibility(hatId, electionModuleAddress); - - IHatsElectionEligibility(electionModuleAddress).elect( - termedParams.termEndDateTs, - termedParams.nominatedWearers - ); - - return electionModuleAddress; } } From 80a133110054127d3bc87fb9ea6255b8fec14371 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:56:17 -0400 Subject: [PATCH 095/206] fix tests --- test/DecentHats.test.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index 22a361d9..e3aa14f2 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -326,7 +326,6 @@ describe("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - }, ] ), @@ -433,7 +432,7 @@ describe("DecentHats", () => { wearer: ethers.ZeroAddress, sablierParams: [ { - sablierV2LockupLinear: mockSablierAddress, + sablier: mockSablierAddress, sender: gnosisSafeAddress, totalAmount: ethers.parseEther("100"), asset: mockERC20Address, @@ -474,7 +473,6 @@ describe("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - }, ] ), @@ -576,7 +574,7 @@ describe("DecentHats", () => { wearer: ethers.ZeroAddress, sablierParams: [ { - sablierV2LockupLinear: mockSablierAddress, + sablier: mockSablierAddress, sender: gnosisSafeAddress, totalAmount: ethers.parseEther("100"), asset: mockERC20Address, @@ -590,7 +588,7 @@ describe("DecentHats", () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, { - sablierV2LockupLinear: mockSablierAddress, + sablier: mockSablierAddress, sender: gnosisSafeAddress, totalAmount: ethers.parseEther("50"), asset: mockERC20Address, @@ -616,7 +614,6 @@ describe("DecentHats", () => { hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, - }, ] ), From 075a281442a4f32ba79721491528958762807fc2 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:58:08 -0400 Subject: [PATCH 096/206] remove flushing of payments when triggering new term --- contracts/DecentAutonomousAdmin.sol | 74 +---------------------------- 1 file changed, 2 insertions(+), 72 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 921f871e..f8fb712a 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -18,7 +18,6 @@ contract DecentAutonomousAdmin { IHats userHatProtocol; uint256 userHatId; address nominatedWearer; - SablierStreamInfo[] sablierStreamInfo; } // ////////////////////////////////////////////////////////////// @@ -48,83 +47,14 @@ contract DecentAutonomousAdmin { hatsElectionModule.startNextTerm(); // transfer user hat to self - args.userHatProtocol.transferHat( + args.userHatProtocol.checkHatWearerStatus( args.userHatId, - args.currentWearer, - address(this) - ); - - // for each withdrawable stream, withdraw funds to current wearer of hat - _flushUnclaimedFunds( - _getStreamsWithUnclaimedFunds(args.sablierStreamInfo), args.currentWearer ); - - // transfer hat to nominated wearer - args.userHatProtocol.transferHat( - args.userHatId, - address(this), - args.nominatedWearer - ); + args.userHatProtocol.mintHat(args.userHatId, args.nominatedWearer); } // ////////////////////////////////////////////////////////////// // Internal Functions // ////////////////////////////////////////////////////////////// - - /** - * @dev Withdraws unclaimed funds from Sablier streams. - * @param _sablierStreamInfo SablierStreamInfo array - */ - function _flushUnclaimedFunds( - SablierStreamInfo[] memory _sablierStreamInfo, - address withdrawTo - ) internal { - for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { - _sablierStreamInfo[i].sablierV2Lockup.withdrawMax( - _sablierStreamInfo[i].streamId, - withdrawTo - ); - } - } - - /** - * @dev Returns an array of Sablier stream ids that have unclaimed funds. - * @param _sablierStreamInfo SablierStreamInfo array - * @return streamsWithUnclaimedFunds An array of SablierStreamInfo that have unclaimed funds - */ - function _getStreamsWithUnclaimedFunds( - SablierStreamInfo[] memory _sablierStreamInfo - ) internal view returns (SablierStreamInfo[] memory) { - uint256 streamsWithUnclaimedFundsCount = 0; - - for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { - uint128 withdrawableAmount = _sablierStreamInfo[i] - .sablierV2Lockup - .withdrawableAmountOf(_sablierStreamInfo[i].streamId); - - if (withdrawableAmount > 0) { - streamsWithUnclaimedFundsCount++; - } - } - - SablierStreamInfo[] - memory streamsWithUnclaimedFunds = new SablierStreamInfo[]( - streamsWithUnclaimedFundsCount - ); - uint256 index = 0; - - for (uint256 i = 0; i < _sablierStreamInfo.length; i++) { - uint128 withdrawableAmount = _sablierStreamInfo[i] - .sablierV2Lockup - .withdrawableAmountOf(_sablierStreamInfo[i].streamId); - - if (withdrawableAmount > 0) { - streamsWithUnclaimedFunds[index] = _sablierStreamInfo[i]; - index++; - } - } - - return streamsWithUnclaimedFunds; - } } From 0c9963bd154c2b73b32da870ec3f8c28dee44f8f Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 19 Oct 2024 04:07:00 -0400 Subject: [PATCH 097/206] termed role payments are direct to nominated wearer --- contracts/DecentHats.sol | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 952ff5e3..48b44cca 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -109,13 +109,6 @@ contract DecentHats { eligibilityAddress ); - if (params.hats[i].isTermed) { - IHatsElectionEligibility(eligibilityAddress).elect( - params.hats[i].termedParams[0].termEndDateTs, - params.hats[i].termedParams[0].nominatedWearers - ); - } - unchecked { ++i; } @@ -221,13 +214,22 @@ contract DecentHats { topHatAccount, eligibilityAddress ); + if (!hat.isTermed) { + accountAddress = _createAccount( + registry, + hatsAccountImplementation, + address(hatsProtocol), + hatId + ); + } else { + IHatsElectionEligibility(eligibilityAddress).elect( + hat.termedParams[0].termEndDateTs, + hat.termedParams[0].nominatedWearers + ); + // Payments are made directly to the hat wearer + accountAddress = hat.wearer; + } - accountAddress = _createAccount( - registry, - hatsAccountImplementation, - address(hatsProtocol), - hatId - ); if (hat.wearer != address(0)) { hatsProtocol.mintHat(hatId, hat.wearer); } From 09cf6c952b0c21359137dcf17714921b7a100e8c Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:29:07 -0400 Subject: [PATCH 098/206] clean up - seperate out logic for minting termed roles --- contracts/DecentHats.sol | 142 +++++++++++++++++++++++++++------------ 1 file changed, 99 insertions(+), 43 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 48b44cca..4f1e931e 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -87,27 +87,33 @@ contract DecentHats { ); for (uint256 i = 0; i < params.hats.length; ) { - address eligibilityAddress = topHatAccount; if (params.hats[i].isTermed) { uint256 hatId = params.hatsProtocol.getNextId(adminHatId); - // Create election module and set as eligiblity, elect, and start next term - eligibilityAddress = _createElectionModule( - params.hatsModuleFactory, - params.hatsElectionEligibilityImplementation, - hatId, - topHatId, - params.hats[i].termedParams[0] + + // Create election module and set as eligiblity + _createTermedHatAndAccountAndMintAndStreams( + params.hatsProtocol, + topHatAccount, + _createElectionEligiblityModule( + params.hatsModuleFactory, + params.hatsElectionEligibilityImplementation, + hatId, + topHatId, + params.hats[i].termedParams[0] + ), + adminHatId, + params.hats[i] + ); + } else { + _createHatAndAccountAndMintAndStreams( + params.hatsProtocol, + params.registry, + topHatAccount, + params.hatsAccountImplementation, + adminHatId, + params.hats[i] ); } - _createHatAndAccountAndMintAndStreams( - params.hatsProtocol, - params.registry, - topHatAccount, - params.hatsAccountImplementation, - adminHatId, - params.hats[i], - eligibilityAddress - ); unchecked { ++i; @@ -204,31 +210,89 @@ contract DecentHats { address topHatAccount, address hatsAccountImplementation, uint256 adminHatId, - Hat calldata hat, - address eligibilityAddress + Hat calldata hat ) internal returns (uint256 hatId, address accountAddress) { hatId = _createHat( hatsProtocol, adminHatId, hat, topHatAccount, - eligibilityAddress + topHatAccount ); - if (!hat.isTermed) { - accountAddress = _createAccount( - registry, - hatsAccountImplementation, - address(hatsProtocol), - hatId + accountAddress = _createAccount( + registry, + hatsAccountImplementation, + address(hatsProtocol), + hatId + ); + + if (hat.wearer != address(0)) { + hatsProtocol.mintHat(hatId, hat.wearer); + } + + for (uint256 i = 0; i < hat.sablierParams.length; ) { + SablierStreamParams memory sablierParams = hat.sablierParams[i]; + + // Approve tokens for Sablier + IAvatar(msg.sender).execTransactionFromModule( + sablierParams.asset, + 0, + abi.encodeWithSignature( + "approve(address,uint256)", + sablierParams.sablier, + sablierParams.totalAmount + ), + Enum.Operation.Call ); - } else { - IHatsElectionEligibility(eligibilityAddress).elect( - hat.termedParams[0].termEndDateTs, - hat.termedParams[0].nominatedWearers + + LockupLinear.CreateWithTimestamps memory params = LockupLinear + .CreateWithTimestamps({ + sender: sablierParams.sender, + recipient: accountAddress, + totalAmount: sablierParams.totalAmount, + asset: IERC20(sablierParams.asset), + cancelable: sablierParams.cancelable, + transferable: sablierParams.transferable, + timestamps: sablierParams.timestamps, + broker: sablierParams.broker + }); + + // Proxy the Sablier call through IAvatar + IAvatar(msg.sender).execTransactionFromModule( + address(sablierParams.sablier), + 0, + abi.encodeWithSignature( + "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", + params + ), + Enum.Operation.Call ); - // Payments are made directly to the hat wearer - accountAddress = hat.wearer; + + unchecked { + ++i; + } } + } + + function _createTermedHatAndAccountAndMintAndStreams( + IHats hatsProtocol, + address topHatAccount, + address eligibilityAddress, + uint256 adminHatId, + Hat calldata hat + ) internal { + uint256 hatId = _createHat( + hatsProtocol, + adminHatId, + hat, + topHatAccount, + eligibilityAddress + ); + + IHatsElectionEligibility(eligibilityAddress).elect( + hat.termedParams[0].termEndDateTs, + hat.termedParams[0].nominatedWearers + ); if (hat.wearer != address(0)) { hatsProtocol.mintHat(hatId, hat.wearer); @@ -252,7 +316,7 @@ contract DecentHats { LockupLinear.CreateWithTimestamps memory params = LockupLinear .CreateWithTimestamps({ sender: sablierParams.sender, - recipient: accountAddress, + recipient: hat.wearer, totalAmount: sablierParams.totalAmount, asset: IERC20(sablierParams.asset), cancelable: sablierParams.cancelable, @@ -307,21 +371,13 @@ contract DecentHats { adminHatId, moduleProxyFactory.deployModule( decentAutonomousAdminMasterCopy, - abi.encodeWithSignature("setUp()"), + abi.encodeWithSignature("setUp(bytes)", bytes("")), uint256(keccak256(abi.encodePacked(SALT, adminHatId))) ) ); } - function _getCreationCode( - uint256 _adminHatId - ) internal pure returns (bytes memory) { - bytes memory bytecode = type(DecentAutonomousAdmin).creationCode; - bytes memory constructorArgs = abi.encode(_adminHatId); - return abi.encodePacked(bytecode, constructorArgs); - } - - function _createElectionModule( + function _createElectionEligiblityModule( IHatsModuleFactory hatsModuleFactory, address hatsElectionEligibilityImplementation, uint256 hatId, From e56fede0b432a6673d7b7ebb6e3f6a0f0ae96349 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:29:26 -0400 Subject: [PATCH 099/206] make factoryFriendly --- contracts/DecentAutonomousAdmin.sol | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index f8fb712a..31030b5b 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -4,10 +4,11 @@ pragma solidity 0.8.28; import {IHats} from "./interfaces/hats/full/IHats.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; +import {FactoryFriendly} from "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol"; -contract DecentAutonomousAdmin { +contract DecentAutonomousAdmin is FactoryFriendly { string public constant NAME = "DecentAutonomousAdmin"; - string public version_ = "0.1.0"; + string public constant version_ = "0.1.0"; struct SablierStreamInfo { uint256 streamId; @@ -23,7 +24,7 @@ contract DecentAutonomousAdmin { // ////////////////////////////////////////////////////////////// // initializer // ////////////////////////////////////////////////////////////// - function setUp() public {} + function setUp(bytes memory initializeParams) public override initializer {} // ////////////////////////////////////////////////////////////// // Public Functions From ffcf907e75b66f86487110254766c8766629538b Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:34:55 -0400 Subject: [PATCH 100/206] revert changes --- contracts/mocks/MockSablierV2LockupLinear.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 327c0eeb..9926a994 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -153,4 +153,4 @@ contract MockSablierV2LockupLinear { return MockLockupLinear.Status.SETTLED; } } -} \ No newline at end of file +} From 78e415139e9666b9ac7db1078fbd9bf0f1288aae Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:36:28 -0400 Subject: [PATCH 101/206] revert changes --- deploy/core/011_deploy_ModuleProxyFactory.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deploy/core/011_deploy_ModuleProxyFactory.ts b/deploy/core/011_deploy_ModuleProxyFactory.ts index 15494c3a..cc106be9 100644 --- a/deploy/core/011_deploy_ModuleProxyFactory.ts +++ b/deploy/core/011_deploy_ModuleProxyFactory.ts @@ -1,11 +1,11 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; +// import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types" // import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; -const func: DeployFunction = async (_: HardhatRuntimeEnvironment) => { +const func: DeployFunction = async (/* hre: HardhatRuntimeEnvironment */) => { // No longer deploying ModuleProxyFactory to any new networks.. // This contract is deployed by the Zodiac team. // await deployNonUpgradeable(hre, "ModuleProxyFactory", []); -}; +} -export default func; +export default func From f424617ec9e081a0a8f528ec2511ddb50a62e39a Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:37:53 -0400 Subject: [PATCH 102/206] change for consistency --- deploy/core/017_deploy_DecentHats_0_1_0.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/core/017_deploy_DecentHats_0_1_0.ts b/deploy/core/017_deploy_DecentHats_0_1_0.ts index 3b66e607..75de4306 100644 --- a/deploy/core/017_deploy_DecentHats_0_1_0.ts +++ b/deploy/core/017_deploy_DecentHats_0_1_0.ts @@ -1,8 +1,8 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types" +// import { HardhatRuntimeEnvironment } from "hardhat/types" import { DeployFunction } from "hardhat-deploy/types" // import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; -const func: DeployFunction = async (_: HardhatRuntimeEnvironment) => { +const func: DeployFunction = async (/* hre: HardhatRuntimeEnvironment */) => { // No longer deploying DecentHats_0_1_0 to any new networks.. // This contract has been depreciated. // await deployNonUpgradeable(hre, "DecentHats_0_1_0"); From 0b6c791cbea894aff60daa82889644d01e807e58 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:38:33 -0400 Subject: [PATCH 103/206] revert change --- test/DecentHats_0_1_0.test.ts | 679 ++++++++++++++++------------------ 1 file changed, 315 insertions(+), 364 deletions(-) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index c75a6c2b..722b8aa0 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -15,71 +15,61 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, -} from "../typechain-types"; +} from "../typechain-types" -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; +import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" +import { expect } from "chai" +import { ethers } from "ethers" +import hre from "hardhat" -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, -} from "./GlobalSafeDeployments.test"; -import { - executeSafeTransaction, - getHatAccount, - predictGnosisSafeAddress, -} from "./helpers"; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test" +import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from "./helpers" describe("DecentHats_0_1_0", () => { - let dao: SignerWithAddress; + let dao: SignerWithAddress - let mockHats: MockHats; - let mockHatsAddress: string; + let mockHats: MockHats + let mockHatsAddress: string - let keyValuePairs: KeyValuePairs; - let gnosisSafe: GnosisSafeL2; + let keyValuePairs: KeyValuePairs + let gnosisSafe: GnosisSafeL2 - let decentHats: DecentHats_0_1_0; - let decentHatsAddress: string; + let decentHats: DecentHats_0_1_0 + let decentHatsAddress: string - let gnosisSafeAddress: string; - let erc6551Registry: ERC6551Registry; + let gnosisSafeAddress: string + let erc6551Registry: ERC6551Registry - let mockHatsAccountImplementation: MockHatsAccount; - let mockHatsAccountImplementationAddress: string; + let mockHatsAccountImplementation: MockHatsAccount + let mockHatsAccountImplementationAddress: string - let mockSablier: MockSablierV2LockupLinear; - let mockSablierAddress: string; + let mockSablier: MockSablierV2LockupLinear + let mockSablierAddress: string - let mockERC20: MockERC20; - let mockERC20Address: string; + let mockERC20: MockERC20 + let mockERC20Address: string beforeEach(async () => { - const signers = await hre.ethers.getSigners(); - const [deployer] = signers; - [, dao] = signers; - - mockHats = await new MockHats__factory(deployer).deploy(); - mockHatsAddress = await mockHats.getAddress(); - keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); - erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory( - deployer - ).deploy(); - mockHatsAccountImplementationAddress = - await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); - decentHatsAddress = await decentHats.getAddress(); - - const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); - const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = - await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + const signers = await hre.ethers.getSigners() + const [deployer] = signers + ;[, dao] = signers + + mockHats = await new MockHats__factory(deployer).deploy() + mockHatsAddress = await mockHats.getAddress() + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress() + decentHats = await new DecentHats_0_1_0__factory(deployer).deploy() + decentHatsAddress = await decentHats.getAddress() + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory() + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton() + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress() + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + "setup", + [ [dao.address], 1, hre.ethers.ZeroAddress, @@ -88,94 +78,91 @@ describe("DecentHats_0_1_0", () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ]); + ] + ) - const saltNum = BigInt( - `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` - ); + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`) const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, gnosisSafeProxyFactory - ); - gnosisSafeAddress = predictedGnosisSafeAddress; + ) + gnosisSafeAddress = predictedGnosisSafeAddress await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, saltNum - ); + ) - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer) // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory( - deployer - ).deploy(); - mockSablierAddress = await mockSablier.getAddress(); + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy() + mockSablierAddress = await mockSablier.getAddress() - mockERC20 = await new MockERC20__factory(deployer).deploy( - "MockERC20", - "MCK" - ); - mockERC20Address = await mockERC20.getAddress(); + mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK") + mockERC20Address = await mockERC20.getAddress() - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); - }); + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")) + }) describe("DecentHats", () => { - let enableModuleTx: ethers.ContractTransactionResponse; + let enableModuleTx: ethers.ContractTransactionResponse beforeEach(async () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: - GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentHatsAddress] - ), + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( + "enableModule", + [decentHatsAddress] + ), signers: [dao], - }); - }); + }) + }) describe("Enabled as a module", () => { it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); - }); + await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an EnabledModule event", async () => { await expect(enableModuleTx) .to.emit(gnosisSafe, "EnabledModule") - .withArgs(decentHatsAddress); - }); - }); + .withArgs(decentHatsAddress) + }) + }) describe("Creating a new Top Hat and Tree", () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + let createAndDeclareTreeTx: ethers.ContractTransactionResponse beforeEach(async () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, details: "", imageURI: "", @@ -183,108 +170,91 @@ describe("DecentHats_0_1_0", () => { wearer: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ] - ), + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + ], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an ExecutionFromModuleSuccess event", async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress); - }); + .withArgs(decentHatsAddress) + }) it("Emits some hatsTreeId ValueUpdated events", async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0"); - }); + .withArgs(gnosisSafeAddress, "topHatId", "0") + }) describe("Multiple calls", () => { - let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; + let createAndDeclareTreeTx2: ethers.ContractTransactionResponse beforeEach(async () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], }, - ] - ), + hats: [], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx2).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); + await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an ExecutionFromModuleSuccess event", async () => { await expect(createAndDeclareTreeTx2) .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress); - }); + .withArgs(decentHatsAddress) + }) it("Creates Top Hats with sequential IDs", async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "4"); - }); - }); + .withArgs(gnosisSafeAddress, "topHatId", "4") + }) + }) describe("Creating Hats Accounts", () => { it("Generates the correct Addresses for the current Hats", async () => { - const currentCount = await mockHats.count(); + const currentCount = await mockHats.count() for (let i = 0n; i < currentCount; i++) { const topHatAccount = await getHatAccount( @@ -292,41 +262,68 @@ describe("DecentHats_0_1_0", () => { erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress - ); + ) - expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq( - mockHatsAddress - ); + expect(await topHatAccount.tokenId()).eq(i) + expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress) } - }); - }); - }); + }) + }) + }) describe("Creating a new Top Hat and Tree with Sablier Streams", () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; - let currentBlockTimestamp: number; + let createAndDeclareTreeTx: ethers.ContractTransactionResponse + let currentBlockTimestamp: number beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + { maxSupply: 1, details: "", imageURI: "", @@ -334,228 +331,182 @@ describe("DecentHats_0_1_0", () => { wearer: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ] - ), + ], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); - }); + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") + }) it("Emits an ExecutionFromModuleSuccess event", async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress); - }); + .withArgs(decentHatsAddress) + }) it("Emits some hatsTreeId ValueUpdated events", async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0"); - }); + .withArgs(gnosisSafeAddress, "topHatId", "0") + }) it("Creates a Sablier stream for the hat with stream parameters", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(1); + ) + expect(streamCreatedEvents.length).to.equal(1) - const event = streamCreatedEvents[0]; - expect(event.args.sender).to.equal(gnosisSafeAddress); - expect(event.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event.args.totalAmount).to.equal(ethers.parseEther("100")); - }); + const event = streamCreatedEvents[0] + expect(event.args.sender).to.equal(gnosisSafeAddress) + expect(event.args.recipient).to.not.equal(ethers.ZeroAddress) + expect(event.args.totalAmount).to.equal(ethers.parseEther("100")) + }) it("Does not create a Sablier stream for hats without stream parameters", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created - }); + ) + expect(streamCreatedEvents.length).to.equal(1) // Only one stream should be created + }) it("Creates a Sablier stream with correct timestamps", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(1); + ) + expect(streamCreatedEvents.length).to.equal(1) - const streamId = streamCreatedEvents[0].args.streamId; - const stream = await mockSablier.getStream(streamId); + const streamId = streamCreatedEvents[0].args.streamId + const stream = await mockSablier.getStream(streamId) - expect(stream.startTime).to.equal(currentBlockTimestamp); - expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000); - }); - }); + expect(stream.startTime).to.equal(currentBlockTimestamp) + expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000) + }) + }) describe("Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat", () => { - let currentBlockTimestamp: number; + let currentBlockTimestamp: number beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + "createAndDeclareTree", + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: "", + topHatImageURI: "", + adminHat: { + maxSupply: 1, + details: "", + imageURI: "", + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, details: "", imageURI: "", isMutable: false, wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("100"), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now }, - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("50"), - asset: mockERC20Address, - cancelable: false, - transferable: true, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, // No cliff - end: currentBlockTimestamp + 1296000, // 15 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther("50"), + asset: mockERC20Address, + cancelable: false, + transferable: true, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, // No cliff + end: currentBlockTimestamp + 1296000, // 15 days from now }, - ], - }, - ], - }, - ] - ), + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + ], + }, + ] + ), signers: [dao], - }); - }); + }) + }) it("Creates multiple Sablier streams for a single hat", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - expect(streamCreatedEvents.length).to.equal(2); + ) + expect(streamCreatedEvents.length).to.equal(2) - const event1 = streamCreatedEvents[0]; - expect(event1.args.sender).to.equal(gnosisSafeAddress); - expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")); + const event1 = streamCreatedEvents[0] + expect(event1.args.sender).to.equal(gnosisSafeAddress) + expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress) + expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")) - const event2 = streamCreatedEvents[1]; - expect(event2.args.sender).to.equal(gnosisSafeAddress); - expect(event2.args.recipient).to.equal(event1.args.recipient); - expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")); - }); + const event2 = streamCreatedEvents[1] + expect(event2.args.sender).to.equal(gnosisSafeAddress) + expect(event2.args.recipient).to.equal(event1.args.recipient) + expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")) + }) it("Creates streams with correct parameters", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); - expect(stream1.cancelable).to.be.true; - expect(stream1.transferable).to.be.false; - expect(stream1.endTime - stream1.startTime).to.equal(2592000); - - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); - expect(stream2.cancelable).to.be.false; - expect(stream2.transferable).to.be.true; - expect(stream2.endTime - stream2.startTime).to.equal(1296000); - }); + ) + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) + expect(stream1.cancelable).to.be.true + expect(stream1.transferable).to.be.false + expect(stream1.endTime - stream1.startTime).to.equal(2592000) + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) + expect(stream2.cancelable).to.be.false + expect(stream2.transferable).to.be.true + expect(stream2.endTime - stream2.startTime).to.equal(1296000) + }) it("Creates streams with correct timestamps", async () => { const streamCreatedEvents = await mockSablier.queryFilter( mockSablier.filters.StreamCreated() - ); - - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); - expect(stream1.startTime).to.equal(currentBlockTimestamp); - expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); - - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); - expect(stream2.startTime).to.equal(currentBlockTimestamp); - expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); - }); - }); - }); -}); \ No newline at end of file + ) + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) + expect(stream1.startTime).to.equal(currentBlockTimestamp) + expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000) + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) + expect(stream2.startTime).to.equal(currentBlockTimestamp) + expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000) + }) + }) + }) +}) From ae18198fcee430b253efb6384b209051b66bbec7 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:41:51 -0400 Subject: [PATCH 104/206] add comments --- contracts/DecentAutonomousAdmin.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 31030b5b..221f8f12 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -47,11 +47,12 @@ contract DecentAutonomousAdmin is FactoryFriendly { hatsElectionModule.startNextTerm(); - // transfer user hat to self + // This will burn the hat since wearer is no longer eligible args.userHatProtocol.checkHatWearerStatus( args.userHatId, args.currentWearer ); + // This will mint the hat to the nominated wearer args.userHatProtocol.mintHat(args.userHatId, args.nominatedWearer); } From 418a93f1c129846cef8afd2c8a8b82af435b0357 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:48:45 -0400 Subject: [PATCH 105/206] small cleanup --- contracts/DecentHats.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 4f1e931e..fc73aa33 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -88,8 +88,6 @@ contract DecentHats { for (uint256 i = 0; i < params.hats.length; ) { if (params.hats[i].isTermed) { - uint256 hatId = params.hatsProtocol.getNextId(adminHatId); - // Create election module and set as eligiblity _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, @@ -97,7 +95,7 @@ contract DecentHats { _createElectionEligiblityModule( params.hatsModuleFactory, params.hatsElectionEligibilityImplementation, - hatId, + params.hatsProtocol.getNextId(adminHatId), topHatId, params.hats[i].termedParams[0] ), From 79ac1f4e28e2aadda7cd9974ff3f1fd61e5f5201 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 22 Oct 2024 01:16:41 -0400 Subject: [PATCH 106/206] add ERC165 support --- contracts/DecentAutonomousAdmin.sol | 33 +++++++++---------- .../interfaces/IDecentAutonomousAdmin.sol | 21 ++++++++++++ 2 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 contracts/interfaces/IDecentAutonomousAdmin.sol diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 221f8f12..7d0fc5df 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -3,24 +3,15 @@ pragma solidity 0.8.28; import {IHats} from "./interfaces/hats/full/IHats.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; -import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; import {FactoryFriendly} from "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol"; - -contract DecentAutonomousAdmin is FactoryFriendly { - string public constant NAME = "DecentAutonomousAdmin"; - string public constant version_ = "0.1.0"; - - struct SablierStreamInfo { - uint256 streamId; - ISablierV2Lockup sablierV2Lockup; - } - struct TriggerStartArgs { - address currentWearer; - IHats userHatProtocol; - uint256 userHatId; - address nominatedWearer; - } - +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {IDecentAutonomousAdmin} from "./interfaces/IDecentAutonomousAdmin.sol"; + +contract DecentAutonomousAdmin is + IDecentAutonomousAdmin, + ERC165, + FactoryFriendly +{ // ////////////////////////////////////////////////////////////// // initializer // ////////////////////////////////////////////////////////////// @@ -56,6 +47,14 @@ contract DecentAutonomousAdmin is FactoryFriendly { args.userHatProtocol.mintHat(args.userHatId, args.nominatedWearer); } + function supportsInterface( + bytes4 interfaceId + ) public view override returns (bool) { + return + interfaceId == type(IDecentAutonomousAdmin).interfaceId || + super.supportsInterface(interfaceId); + } + // ////////////////////////////////////////////////////////////// // Internal Functions // ////////////////////////////////////////////////////////////// diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentAutonomousAdmin.sol new file mode 100644 index 00000000..ae4a7e34 --- /dev/null +++ b/contracts/interfaces/IDecentAutonomousAdmin.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import {IHats} from "./hats/full/IHats.sol"; +import {ISablierV2Lockup} from "./sablier/full/ISablierV2Lockup.sol"; + +interface IDecentAutonomousAdmin { + struct SablierStreamInfo { + uint256 streamId; + ISablierV2Lockup sablierV2Lockup; + } + + struct TriggerStartArgs { + address currentWearer; + IHats userHatProtocol; + uint256 userHatId; + address nominatedWearer; + } + + function triggerStartNextTerm(TriggerStartArgs calldata args) external; +} From 3dace31dbee9797e1d90f425a86d73a6e917e3fa Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 22 Oct 2024 11:09:42 -0400 Subject: [PATCH 107/206] Install lint and pretty tools and configs --- .eslintrc.json | 43 + .prettierignore | 1 + .prettierrc | 10 + package-lock.json | 2111 ++++++++++++++++++++++++++++----------------- package.json | 15 +- 5 files changed, 1398 insertions(+), 782 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..ed6d7f02 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,43 @@ +{ + "env": { + "es2021": true + }, + "extends": ["plugin:import/recommended", "airbnb-typescript/base", "prettier"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + // required for "type-aware linting" + "project": ["./tsconfig.json"], + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["import", "@typescript-eslint"], + "settings": { + // resolves imports without file extensions for listed extensions + "import/resolver": { + "node": { + "extensions": [".ts"] + } + } + }, + "rules": { + "comma-dangle": "off", + "@typescript-eslint/comma-dangle": "off", + "indent": "off", + "@typescript-eslint/indent": "off", + "import/order": [ + "error", + { + "alphabetize": { + "order": "asc", + "caseInsensitive": false + } + } + ], + // var rules + "no-use-before-define": "off", + "@typescript-eslint/no-use-before-define": "error", + "@typescript-eslint/no-unused-vars": "warn", + // class rules + "@typescript-eslint/lines-between-class-members": "off" + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..5d5689b3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +deployments/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..90a9a138 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,10 @@ +{ + "printWidth": 100, + "endOfLine": "auto", + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "semi": true, + "arrowParens": "avoid", + "singleAttributePerLine": true +} diff --git a/package-lock.json b/package-lock.json index 7aa16857..5d05df06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,16 +8,25 @@ "name": "@fractal-framework/fractal-contracts", "version": "1.2.16", "license": "MIT", - "devDependencies": { + "dependencies": { "@gnosis.pm/zodiac": "^1.1.4", + "@nomicfoundation/hardhat-ethers": "^3.0.5", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0", "@prb/math": "^4.0.3", + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "chai": "^4.2.0", "dotenv": "^16.4.5", + "eslint": "^8.22.0", + "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", "hardhat": "^2.22.2", "hardhat-dependency-compiler": "^1.1.4", "hardhat-deploy": "^0.12.2", + "prettier": "^3.3.3", "solidity-docgen": "^0.6.0-beta.36" } }, @@ -25,14 +34,12 @@ "version": "1.10.1", "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", - "dev": true, "peer": true }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "peer": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -41,11 +48,82 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@ethereumjs/rlp": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "dev": true, "peer": true, "bin": { "rlp": "bin/rlp" @@ -58,7 +136,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", - "dev": true, "peer": true, "dependencies": { "@ethereumjs/rlp": "^4.0.1", @@ -73,7 +150,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "1.3.3" @@ -86,7 +162,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "dev": true, "peer": true, "engines": { "node": ">= 16" @@ -99,7 +174,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", - "dev": true, "peer": true, "dependencies": { "@noble/curves": "1.3.0", @@ -112,7 +186,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, "funding": [ { "type": "individual", @@ -139,7 +212,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, "funding": [ { "type": "individual", @@ -164,7 +236,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, "funding": [ { "type": "individual", @@ -187,7 +258,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, "funding": [ { "type": "individual", @@ -210,7 +280,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, "funding": [ { "type": "individual", @@ -229,7 +298,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, "funding": [ { "type": "individual", @@ -249,7 +317,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, "funding": [ { "type": "individual", @@ -270,7 +337,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, "funding": [ { "type": "individual", @@ -289,7 +355,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, "funding": [ { "type": "individual", @@ -308,7 +373,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, "funding": [ { "type": "individual", @@ -336,7 +400,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, "funding": [ { "type": "individual", @@ -363,7 +426,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, "funding": [ { "type": "individual", @@ -393,7 +455,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, "funding": [ { "type": "individual", @@ -423,14 +484,12 @@ "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" }, "node_modules/@ethersproject/keccak256": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, "funding": [ { "type": "individual", @@ -450,7 +509,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true, "funding": [ { "type": "individual", @@ -466,7 +524,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "dev": true, "funding": [ { "type": "individual", @@ -485,7 +542,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, "funding": [ { "type": "individual", @@ -505,7 +561,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, "funding": [ { "type": "individual", @@ -524,7 +579,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, "funding": [ { "type": "individual", @@ -562,7 +616,6 @@ "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, "engines": { "node": ">=8.3.0" }, @@ -583,7 +636,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, "funding": [ { "type": "individual", @@ -603,7 +655,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, "funding": [ { "type": "individual", @@ -623,7 +674,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, "funding": [ { "type": "individual", @@ -644,7 +694,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, "funding": [ { "type": "individual", @@ -668,7 +717,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, "funding": [ { "type": "individual", @@ -692,7 +740,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, "funding": [ { "type": "individual", @@ -713,7 +760,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, "funding": [ { "type": "individual", @@ -740,7 +786,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, "funding": [ { "type": "individual", @@ -761,7 +806,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, "funding": [ { "type": "individual", @@ -794,7 +838,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "dev": true, "funding": [ { "type": "individual", @@ -817,7 +860,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, "funding": [ { "type": "individual", @@ -840,7 +882,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "dev": true, "engines": { "node": ">=14" } @@ -848,14 +889,12 @@ "node_modules/@gnosis.pm/mock-contract": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@gnosis.pm/mock-contract/-/mock-contract-4.0.0.tgz", - "integrity": "sha512-SkRq2KwPx6vo0LAjSc8JhgQstrQFXRyn2yqquIfub7r2WHi5nUbF8beeSSXsd36hvBcQxQfmOIYNYRpj9JOhrQ==", - "dev": true + "integrity": "sha512-SkRq2KwPx6vo0LAjSc8JhgQstrQFXRyn2yqquIfub7r2WHi5nUbF8beeSSXsd36hvBcQxQfmOIYNYRpj9JOhrQ==" }, "node_modules/@gnosis.pm/safe-contracts": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@gnosis.pm/safe-contracts/-/safe-contracts-1.3.0.tgz", "integrity": "sha512-1p+1HwGvxGUVzVkFjNzglwHrLNA67U/axP0Ct85FzzH8yhGJb4t9jDjPYocVMzLorDoWAfKicGy1akPY9jXRVw==", - "dev": true, "peerDependencies": { "ethers": "^5.1.4" } @@ -864,7 +903,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/@gnosis.pm/zodiac/-/zodiac-1.1.4.tgz", "integrity": "sha512-qELBXyD6lf3S0hcKnsiy4K5ThonBhgkTiKfhr57biO/NLLZOXf7HEXe/PA322jEMMYbohgWfcaFspUDQcVpfNA==", - "dev": true, "dependencies": { "@gnosis.pm/mock-contract": "^4.0.0", "@gnosis.pm/safe-contracts": "1.3.0", @@ -881,7 +919,6 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, "engines": { "node": ">= 12" } @@ -890,7 +927,6 @@ "version": "8.6.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, "engines": { "node": ">=10" } @@ -899,7 +935,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, "funding": [ { "type": "individual", @@ -947,7 +982,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -956,7 +990,6 @@ "version": "0.8.25", "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.25.tgz", "integrity": "sha512-7P0TF8gPeudl1Ko3RGkyY6XVCxe2SdD/qQhtns1vl3yAbK/PDifKDLHGtx1t7mX3LgR7ojV7Fg/Kc6Q9D2T8UQ==", - "dev": true, "dependencies": { "command-exists": "^1.2.8", "commander": "^8.1.0", @@ -973,11 +1006,42 @@ "node": ">=10.0.0" } }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead" + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "peer": true, "engines": { "node": ">=6.0.0" @@ -987,14 +1051,12 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true, "peer": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -1005,7 +1067,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, "dependencies": { "ethereumjs-abi": "^0.6.8", "ethereumjs-util": "^6.2.1", @@ -1021,7 +1082,6 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -1029,14 +1089,12 @@ "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "dependencies": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -1051,7 +1109,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "1.3.2" @@ -1064,7 +1121,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, "peer": true, "engines": { "node": ">= 16" @@ -1077,7 +1133,6 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", - "dev": true, "funding": [ { "type": "individual", @@ -1089,8 +1144,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "peer": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1103,8 +1156,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "peer": true, "engines": { "node": ">= 8" } @@ -1113,8 +1164,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "peer": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1127,7 +1176,6 @@ "version": "0.3.4", "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.3.4.tgz", "integrity": "sha512-e4jzVeJ+VTKBFzNgKDbSVnGVbHYNZHIfMdgifQBugXPiIa6QEUzZqleh2+y4lhkXcCthnFyrTYe3jiEpUzr3cA==", - "dev": true, "engines": { "node": ">= 18" }, @@ -1150,7 +1198,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1166,7 +1213,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1182,7 +1228,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1198,7 +1243,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1214,7 +1258,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1230,7 +1273,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1246,7 +1288,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1262,7 +1303,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1278,7 +1318,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1291,7 +1330,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", - "dev": true, "dependencies": { "@nomicfoundation/ethereumjs-util": "9.0.4" } @@ -1300,7 +1338,6 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", - "dev": true, "bin": { "rlp": "bin/rlp.cjs" }, @@ -1312,7 +1349,6 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", - "dev": true, "dependencies": { "@nomicfoundation/ethereumjs-common": "4.0.4", "@nomicfoundation/ethereumjs-rlp": "5.0.4", @@ -1335,7 +1371,6 @@ "version": "9.0.4", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", - "dev": true, "dependencies": { "@nomicfoundation/ethereumjs-rlp": "5.0.4", "ethereum-cryptography": "0.1.3" @@ -1356,7 +1391,6 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz", "integrity": "sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==", - "dev": true, "peer": true, "dependencies": { "@types/chai-as-promised": "^7.1.3", @@ -1375,8 +1409,6 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz", "integrity": "sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==", - "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.1", "lodash.isequal": "^4.5.0" @@ -1390,7 +1422,6 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.1.tgz", "integrity": "sha512-hWV/W9ZdG9HIqUiQXexrwoBBGP4IrDLghlZPAXXEXETmJ2AVPnBKQG626YmAYgEk2G3vX9ojn16daT+H2i/mFA==", - "dev": true, "peer": true, "dependencies": { "@nomicfoundation/ignition-core": "^0.15.1", @@ -1409,7 +1440,6 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.1.tgz", "integrity": "sha512-FPeE0EbJ+RcBGro9TxODyDffpSPhnG8ra43nJp7/1H2M0S+UkmJUeZlSjAIVfUut1zMwy+57j+PNn07dOr/YmQ==", - "dev": true, "peer": true, "peerDependencies": { "@nomicfoundation/hardhat-ethers": "^3.0.4", @@ -1423,7 +1453,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.10.tgz", "integrity": "sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ==", - "dev": true, "peer": true, "dependencies": { "ethereumjs-util": "^7.1.4" @@ -1436,7 +1465,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", - "dev": true, "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.0", @@ -1462,7 +1490,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.5.tgz", "integrity": "sha512-Tg4zu8RkWpyADSFIgF4FlJIUEI4VkxcvELsmbJn2OokbvH2SnUrqKmw0BBfDrtvP0hhmx8wsnrRKP5DV/oTyTA==", - "dev": true, "peer": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -1483,7 +1510,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "peer": true, "dependencies": { "color-convert": "^1.9.0" @@ -1496,7 +1522,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "peer": true, "dependencies": { "ansi-styles": "^3.2.1", @@ -1511,7 +1536,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "peer": true, "dependencies": { "color-name": "1.1.3" @@ -1521,14 +1545,12 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, "peer": true }, "node_modules/@nomicfoundation/hardhat-verify/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "peer": true, "engines": { "node": ">=0.8.0" @@ -1538,7 +1560,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -1548,7 +1569,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "peer": true, "dependencies": { "has-flag": "^3.0.0" @@ -1561,7 +1581,6 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.1.tgz", "integrity": "sha512-/AZO0YHRv1+yQSOtSSbg4GEH9YhU8EVePSfByU2PZW2bsAK0SA8GdoLYFbVNl140dogem5lrE+bCKtX0eN/n+A==", - "dev": true, "peer": true, "dependencies": { "@ethersproject/address": "5.6.1", @@ -1579,7 +1598,6 @@ "version": "5.6.1", "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", - "dev": true, "funding": [ { "type": "individual", @@ -1603,7 +1621,6 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", - "dev": true, "peer": true, "dependencies": { "nofilter": "^3.1.0" @@ -1616,14 +1633,12 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.1.tgz", "integrity": "sha512-ecx6M9K4IeF7L0XCcHg0E72zlVaGSOlkhb/9XuWrA2ltfB/e4ZsOhVxXtwDf9xIcaq7tUdMSxyj6Ld0bPAhxAw==", - "dev": true, "peer": true }, "node_modules/@nomicfoundation/solidity-analyzer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", "integrity": "sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==", - "dev": true, "engines": { "node": ">= 12" }, @@ -1647,7 +1662,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1663,7 +1677,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1679,7 +1692,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -1695,7 +1707,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1711,7 +1722,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1727,7 +1737,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1743,7 +1752,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1759,7 +1767,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1775,7 +1782,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1791,7 +1797,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1803,26 +1808,27 @@ "node_modules/@openzeppelin/contracts": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz", - "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==", - "dev": true + "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==" }, "node_modules/@openzeppelin/contracts-upgradeable": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.3.tgz", - "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==", - "dev": true + "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==" }, "node_modules/@prb/math": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@prb/math/-/math-4.0.3.tgz", - "integrity": "sha512-/RSt3VU1k2m3ox6U6kUL1MrktnAHr8vhydXu4eDtqFAms1gm3XnGpoZIPaK1lm2zdJQmKBwJ4EXALPARsuOlaA==", - "dev": true + "integrity": "sha512-/RSt3VU1k2m3ox6U6kUL1MrktnAHr8vhydXu4eDtqFAms1gm3XnGpoZIPaK1lm2zdJQmKBwJ4EXALPARsuOlaA==" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==" }, "node_modules/@scure/base": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", "integrity": "sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==", - "dev": true, "funding": { "url": "https://paulmillr.com/funding/" } @@ -1831,7 +1837,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.3.tgz", "integrity": "sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==", - "dev": true, "peer": true, "dependencies": { "@noble/curves": "~1.3.0", @@ -1846,7 +1851,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "1.3.3" @@ -1859,7 +1863,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "dev": true, "peer": true, "engines": { "node": ">= 16" @@ -1872,7 +1875,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.2.tgz", "integrity": "sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "~1.3.2", @@ -1886,7 +1888,6 @@ "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", - "dev": true, "dependencies": { "@sentry/hub": "5.30.0", "@sentry/minimal": "5.30.0", @@ -1901,14 +1902,12 @@ "node_modules/@sentry/core/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/hub": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", - "dev": true, "dependencies": { "@sentry/types": "5.30.0", "@sentry/utils": "5.30.0", @@ -1921,14 +1920,12 @@ "node_modules/@sentry/hub/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/minimal": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", - "dev": true, "dependencies": { "@sentry/hub": "5.30.0", "@sentry/types": "5.30.0", @@ -1941,14 +1938,12 @@ "node_modules/@sentry/minimal/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/node": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", - "dev": true, "dependencies": { "@sentry/core": "5.30.0", "@sentry/hub": "5.30.0", @@ -1967,14 +1962,12 @@ "node_modules/@sentry/node/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/tracing": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", - "dev": true, "dependencies": { "@sentry/hub": "5.30.0", "@sentry/minimal": "5.30.0", @@ -1989,14 +1982,12 @@ "node_modules/@sentry/tracing/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@sentry/types": { "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", - "dev": true, "engines": { "node": ">=6" } @@ -2005,7 +1996,6 @@ "version": "5.30.0", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", - "dev": true, "dependencies": { "@sentry/types": "5.30.0", "tslib": "^1.9.3" @@ -2017,14 +2007,12 @@ "node_modules/@sentry/utils/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@solidity-parser/parser": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", - "dev": true, "peer": true, "dependencies": { "antlr4ts": "^0.5.0-alpha.4" @@ -2034,35 +2022,30 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, "peer": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, "peer": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, "peer": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, "peer": true }, "node_modules/@typechain/ethers-v6": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", - "dev": true, "peer": true, "dependencies": { "lodash": "^4.17.15", @@ -2078,7 +2061,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", - "dev": true, "peer": true, "dependencies": { "fs-extra": "^9.1.0" @@ -2094,7 +2076,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, "peer": true, "dependencies": { "at-least-node": "^1.0.0", @@ -2110,7 +2091,6 @@ "version": "5.1.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -2119,14 +2099,12 @@ "version": "4.3.14", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", - "dev": true, "peer": true }, "node_modules/@types/chai-as-promised": { "version": "7.1.8", "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", - "dev": true, "peer": true, "dependencies": { "@types/chai": "*" @@ -2136,7 +2114,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dev": true, "peer": true, "dependencies": { "@types/node": "*" @@ -2146,7 +2123,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dev": true, "peer": true, "dependencies": { "@types/node": "*" @@ -2156,38 +2132,38 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, "peer": true, "dependencies": { "@types/minimatch": "*", "@types/node": "*" } }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", - "dev": true + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==" }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, "peer": true }, "node_modules/@types/mocha": { "version": "10.0.6", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", - "dev": true, "peer": true }, "node_modules/@types/node": { "version": "20.12.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -2196,7 +2172,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -2205,37 +2180,265 @@ "version": "2.7.3", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", - "dev": true, "peer": true }, "node_modules/@types/qs": { "version": "6.9.14", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", - "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", - "dev": true + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==" }, "node_modules/@types/secp256k1": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", - "dev": true, "dependencies": { "@types/node": "*" } }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, "node_modules/abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true, "peer": true }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2243,11 +2446,18 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, "peer": true, "engines": { "node": ">=0.4.0" @@ -2257,7 +2467,6 @@ "version": "0.4.16", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", - "dev": true, "engines": { "node": ">=0.3.0" } @@ -2266,14 +2475,12 @@ "version": "4.0.0-beta.5", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "dev": true, "peer": true }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, "dependencies": { "debug": "4" }, @@ -2285,7 +2492,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -2298,7 +2504,6 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -2315,7 +2520,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", - "dev": true, "optional": true, "peer": true, "engines": { @@ -2326,7 +2530,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, "dependencies": { "string-width": "^4.1.0" } @@ -2335,7 +2538,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, "engines": { "node": ">=6" } @@ -2344,7 +2546,6 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "dependencies": { "type-fest": "^0.21.3" }, @@ -2359,7 +2560,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -2368,7 +2568,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2383,14 +2582,12 @@ "version": "0.5.0-alpha.4", "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", - "dev": true, "peer": true }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2403,21 +2600,18 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, "peer": true }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/argv": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==", "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, "engines": { "node": ">=0.6.10" } @@ -2426,7 +2620,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, "peer": true, "engines": { "node": ">=6" @@ -2436,7 +2629,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "is-array-buffer": "^3.0.4" @@ -2448,12 +2640,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -2462,7 +2671,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -2472,7 +2680,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -2488,11 +2695,63 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.5", @@ -2514,15 +2773,12 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true, "peer": true }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "peer": true, "engines": { "node": "*" } @@ -2531,7 +2787,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, "peer": true, "engines": { "node": ">=8" @@ -2541,20 +2796,17 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true, "peer": true }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, "peer": true, "engines": { "node": ">= 4.0.0" @@ -2564,7 +2816,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, "dependencies": { "possible-typed-array-names": "^1.0.0" }, @@ -2579,7 +2830,6 @@ "version": "1.6.8", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", - "dev": true, "peer": true, "dependencies": { "follow-redirects": "^1.15.6", @@ -2590,14 +2840,12 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base-x": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" } @@ -2605,14 +2853,12 @@ "node_modules/bech32": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, "engines": { "node": ">=8" }, @@ -2623,20 +2869,17 @@ "node_modules/blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" }, "node_modules/bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" }, "node_modules/boxen": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^6.2.0", @@ -2658,7 +2901,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -2670,7 +2912,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2680,7 +2921,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -2691,20 +2931,17 @@ "node_modules/brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "node_modules/browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -2718,7 +2955,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, "dependencies": { "base-x": "^3.0.2" } @@ -2727,7 +2963,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, "dependencies": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -2737,20 +2972,17 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -2759,7 +2991,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2774,11 +3005,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, "engines": { "node": ">=10" }, @@ -2790,14 +3028,12 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true, "peer": true }, "node_modules/cbor": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, "peer": true, "dependencies": { "nofilter": "^3.1.0" @@ -2810,8 +3046,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "peer": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -2829,7 +3063,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, "peer": true, "dependencies": { "check-error": "^1.0.2" @@ -2842,7 +3075,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2858,7 +3090,6 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", - "dev": true, "peer": true, "engines": { "node": "*" @@ -2868,8 +3099,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "peer": true, "dependencies": { "get-func-name": "^2.0.2" }, @@ -2881,7 +3110,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2904,14 +3132,12 @@ "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "node_modules/cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -2921,7 +3147,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, "engines": { "node": ">=6" } @@ -2930,7 +3155,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true, "engines": { "node": ">=6" }, @@ -2942,7 +3166,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", - "dev": true, "peer": true, "dependencies": { "object-assign": "^4.1.0", @@ -2959,7 +3182,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -2969,7 +3191,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -2979,7 +3200,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "peer": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", @@ -2993,7 +3213,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, "peer": true, "dependencies": { "ansi-regex": "^3.0.0" @@ -3006,7 +3225,6 @@ "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -3017,7 +3235,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -3028,14 +3245,12 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, "peer": true, "engines": { "node": ">=0.1.90" @@ -3045,7 +3260,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3056,14 +3270,12 @@ "node_modules/command-exists": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", - "dev": true + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==" }, "node_modules/command-line-args": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, "peer": true, "dependencies": { "array-back": "^3.1.0", @@ -3079,7 +3291,6 @@ "version": "6.1.3", "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", - "dev": true, "peer": true, "dependencies": { "array-back": "^4.0.2", @@ -3095,7 +3306,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "peer": true, "dependencies": { "color-convert": "^1.9.0" @@ -3108,7 +3318,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, "peer": true, "engines": { "node": ">=8" @@ -3118,7 +3327,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "peer": true, "dependencies": { "ansi-styles": "^3.2.1", @@ -3133,7 +3341,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "peer": true, "dependencies": { "color-name": "1.1.3" @@ -3143,14 +3350,12 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, "peer": true }, "node_modules/command-line-usage/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "peer": true, "engines": { "node": ">=0.8.0" @@ -3160,7 +3365,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -3170,7 +3374,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "peer": true, "dependencies": { "has-flag": "^3.0.0" @@ -3183,7 +3386,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, "peer": true, "engines": { "node": ">=8" @@ -3192,20 +3394,17 @@ "node_modules/commander": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, "engines": [ "node >= 0.8" ], @@ -3221,7 +3420,6 @@ "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "peer": true, "dependencies": { "core-util-is": "~1.0.0", @@ -3237,24 +3435,26 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, "peer": true }, "node_modules/concat-stream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -3263,14 +3463,12 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, "peer": true }, "node_modules/create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -3283,7 +3481,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -3297,14 +3494,39 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, "peer": true }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", - "dev": true, "peer": true, "engines": { "node": "*" @@ -3314,7 +3536,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -3331,7 +3552,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -3348,7 +3568,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -3365,14 +3584,12 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true, "peer": true }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3389,7 +3606,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -3401,8 +3617,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "peer": true, "dependencies": { "type-detect": "^4.0.0" }, @@ -3414,7 +3628,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "peer": true, "engines": { "node": ">=4.0.0" @@ -3423,15 +3636,12 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "peer": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -3448,7 +3658,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -3465,7 +3674,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -3474,7 +3682,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -3483,7 +3690,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, "engines": { "node": ">=0.3.1" } @@ -3492,7 +3698,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", - "dev": true, "peer": true, "dependencies": { "heap": ">= 0.2.0" @@ -3505,8 +3710,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "peer": true, "dependencies": { "path-type": "^4.0.0" }, @@ -3514,11 +3717,21 @@ "node": ">=8" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dotenv": { "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, "engines": { "node": ">=12" }, @@ -3530,7 +3743,6 @@ "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -3544,26 +3756,22 @@ "node_modules/elliptic/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/encode-utf8": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "dev": true + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" @@ -3576,7 +3784,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, "engines": { "node": ">=6" } @@ -3585,7 +3792,6 @@ "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -3645,7 +3851,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -3657,7 +3862,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -3666,7 +3870,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -3678,7 +3881,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, "dependencies": { "get-intrinsic": "^1.2.4", "has-tostringtag": "^1.0.2", @@ -3692,7 +3894,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, "dependencies": { "hasown": "^2.0.0" } @@ -3701,7 +3902,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -3718,7 +3918,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, "engines": { "node": ">=6" } @@ -3727,7 +3926,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -3739,7 +3937,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", - "dev": true, "peer": true, "dependencies": { "esprima": "^2.7.1", @@ -3758,11 +3955,409 @@ "source-map": "~0.2.0" } }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-airbnb-typescript": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-18.0.0.tgz", + "integrity": "sha512-oc+Lxzgzsu8FQyFVa4QFaVKiitTYiiW3frB9KYW5OWdPrqFc7FzxgB20hP4cHMlr+MBzGcLl3jnCOVOydL9mIg==", + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/eslint/node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint/node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", - "dev": true, "peer": true, "bin": { "esparse": "bin/esparse.js", @@ -3772,11 +4367,48 @@ "node": ">=0.10.0" } }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/estraverse": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -3786,8 +4418,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -3796,7 +4426,6 @@ "version": "0.2.27", "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", - "dev": true, "peer": true, "dependencies": { "@solidity-parser/parser": "^0.14.0", @@ -3826,7 +4455,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true, "funding": [ { "type": "individual", @@ -3839,7 +4467,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, "funding": [ { "type": "individual", @@ -3857,7 +4484,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, "funding": [ { "type": "individual", @@ -3874,7 +4500,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "1.2.0", @@ -3887,7 +4512,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, "funding": [ { "type": "individual", @@ -3936,7 +4560,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz", "integrity": "sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "^1.4.0" @@ -3946,7 +4569,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, "peer": true, "engines": { "node": ">= 16" @@ -3959,7 +4581,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, "dependencies": { "@types/pbkdf2": "^3.0.0", "@types/secp256k1": "^4.0.1", @@ -3982,7 +4603,6 @@ "version": "0.6.8", "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, "dependencies": { "bn.js": "^4.11.8", "ethereumjs-util": "^6.0.0" @@ -3992,7 +4612,6 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4000,14 +4619,12 @@ "node_modules/ethereumjs-abi/node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "dependencies": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -4022,7 +4639,6 @@ "version": "7.1.5", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, "peer": true, "dependencies": { "@types/bn.js": "^5.1.0", @@ -4039,7 +4655,6 @@ "version": "6.11.1", "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.11.1.tgz", "integrity": "sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==", - "dev": true, "funding": [ { "type": "individual", @@ -4068,14 +4683,12 @@ "version": "18.15.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "dev": true, "peer": true }, "node_modules/ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", - "dev": true, "peer": true, "dependencies": { "bn.js": "4.11.6", @@ -4090,14 +4703,12 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, "peer": true }, "node_modules/ethjs-util": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, "dependencies": { "is-hex-prefixed": "1.0.0", "strip-hex-prefix": "1.0.0" @@ -4111,7 +4722,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -4120,16 +4730,12 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "peer": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "peer": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -4141,28 +4747,39 @@ "node": ">=8.6.0" } }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "peer": true, "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4174,7 +4791,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, "peer": true, "dependencies": { "array-back": "^3.0.1" @@ -4187,7 +4803,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, "dependencies": { "locate-path": "^2.0.0" }, @@ -4199,16 +4814,47 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, "bin": { "flat": "cli.js" } }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" + }, "node_modules/fmix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", - "dev": true, "dependencies": { "imul": "^1.0.0" } @@ -4217,7 +4863,6 @@ "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true, "funding": [ { "type": "individual", @@ -4237,7 +4882,6 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, "dependencies": { "is-callable": "^1.1.3" } @@ -4246,7 +4890,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -4259,14 +4902,12 @@ "node_modules/fp-ts": { "version": "1.19.3", "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==" }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -4280,20 +4921,17 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", - "dev": true, "peer": true }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -4307,7 +4945,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4316,7 +4953,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -4334,7 +4970,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4343,7 +4978,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -4352,8 +4986,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "peer": true, "engines": { "node": "*" } @@ -4362,7 +4994,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -4381,7 +5012,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -4391,7 +5021,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "es-errors": "^1.3.0", @@ -4408,7 +5037,6 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, "peer": true, "dependencies": { "chalk": "^2.4.2", @@ -4422,7 +5050,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "peer": true, "dependencies": { "color-convert": "^1.9.0" @@ -4435,7 +5062,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "peer": true, "dependencies": { "ansi-styles": "^3.2.1", @@ -4450,7 +5076,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "peer": true, "dependencies": { "color-name": "1.1.3" @@ -4460,14 +5085,12 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, "peer": true }, "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "peer": true, "engines": { "node": ">=0.8.0" @@ -4477,7 +5100,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -4487,7 +5109,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "peer": true, "dependencies": { "has-flag": "^3.0.0" @@ -4500,7 +5121,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4520,7 +5140,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -4532,7 +5151,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, "peer": true, "dependencies": { "global-prefix": "^3.0.0" @@ -4545,7 +5163,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, "peer": true, "dependencies": { "ini": "^1.3.5", @@ -4556,11 +5173,35 @@ "node": ">=6" } }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -4575,7 +5216,6 @@ "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, "peer": true, "dependencies": { "@types/glob": "^7.1.1", @@ -4595,7 +5235,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -4606,14 +5245,17 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -4634,7 +5276,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4643,7 +5284,6 @@ "version": "2.22.2", "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.2.tgz", "integrity": "sha512-0xZ7MdCZ5sJem4MrvpQWLR3R3zGDoHw5lsR+pBFimqwagimIOn3bWuZv69KA+veXClwI1s/zpqgwPwiFrd4Dxw==", - "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", @@ -4709,7 +5349,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.4.tgz", "integrity": "sha512-bEsNwSU2owIcKTRJS1vz/VTI1mILfSYiI/4Zcwee99XC41uQIcDDSvJOdIveeMyO7E50JLg2lZet7oIxTC9Gyg==", - "dev": true, "engines": { "node": ">=14.14.0" }, @@ -4721,7 +5360,6 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.12.2.tgz", "integrity": "sha512-Xp/4Lb5lC/j3kvitaWW5IZN5Meqv5D3kTIifc3ZwBoQtFLN26/fDfRV6MWAAcRO9gH64hZVokvtcDdl/fd7w3A==", - "dev": true, "dependencies": { "@ethersproject/abi": "^5.7.0", "@ethersproject/abstract-signer": "^5.7.0", @@ -4753,7 +5391,6 @@ "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, "dependencies": { "follow-redirects": "^1.14.0" } @@ -4762,7 +5399,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, "funding": [ { "type": "individual", @@ -4810,7 +5446,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", - "dev": true, "peer": true, "dependencies": { "array-uniq": "1.0.3", @@ -4825,7 +5460,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true, "funding": [ { "type": "individual", @@ -4837,7 +5471,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "dev": true, "funding": [ { "type": "individual", @@ -4854,7 +5487,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "dev": true, "funding": [ { "type": "individual", @@ -4870,7 +5502,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -4882,7 +5513,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -4896,7 +5526,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -4904,14 +5533,12 @@ "node_modules/hardhat/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/hardhat/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -4920,7 +5547,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", - "dev": true, "dependencies": { "@noble/hashes": "1.2.0", "@noble/secp256k1": "1.7.1", @@ -4932,7 +5558,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -4946,7 +5571,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -4955,7 +5579,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -4964,7 +5587,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -4976,7 +5598,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -4985,7 +5606,6 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, "engines": { "node": ">=8.3.0" }, @@ -5006,7 +5626,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5015,7 +5634,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -5024,7 +5642,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -5036,7 +5653,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5048,7 +5664,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5060,7 +5675,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -5075,7 +5689,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -5089,7 +5702,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -5099,7 +5711,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -5111,7 +5722,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, "bin": { "he": "bin/he" } @@ -5120,14 +5730,12 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true, "peer": true }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -5138,7 +5746,6 @@ "version": "8.1.3", "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dev": true, "peer": true, "dependencies": { "caseless": "^0.12.0", @@ -5154,7 +5761,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -5170,7 +5776,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dev": true, "peer": true, "dependencies": { "@types/node": "^10.0.3" @@ -5180,14 +5785,12 @@ "version": "10.17.60", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true, "peer": true }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -5200,7 +5803,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5212,8 +5814,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "peer": true, "engines": { "node": ">= 4" } @@ -5222,7 +5822,6 @@ "version": "10.0.2", "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", - "dev": true, "peer": true, "funding": { "type": "opencollective", @@ -5232,23 +5831,51 @@ "node_modules/immutable": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", - "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", - "dev": true + "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } }, "node_modules/imul": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, "engines": { "node": ">=8" } @@ -5257,7 +5884,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5266,21 +5892,18 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, "peer": true }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.0", @@ -5294,7 +5917,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, "peer": true, "engines": { "node": ">= 0.10" @@ -5304,7 +5926,6 @@ "version": "1.10.4", "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, "dependencies": { "fp-ts": "^1.0.0" } @@ -5313,7 +5934,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1" @@ -5329,7 +5949,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -5341,7 +5960,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -5353,7 +5971,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5369,7 +5986,20 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dependencies": { + "hasown": "^2.0.2" + }, "engines": { "node": ">= 0.4" }, @@ -5381,7 +6011,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, "dependencies": { "is-typed-array": "^1.1.13" }, @@ -5396,7 +6025,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5411,7 +6039,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5420,7 +6047,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "engines": { "node": ">=8" } @@ -5429,7 +6055,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -5441,7 +6066,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true, "engines": { "node": ">=6.5.0", "npm": ">=3" @@ -5451,7 +6075,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, "engines": { "node": ">= 0.4" }, @@ -5463,7 +6086,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -5472,7 +6094,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5483,11 +6104,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, "engines": { "node": ">=8" } @@ -5496,7 +6124,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -5512,7 +6139,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, "dependencies": { "call-bind": "^1.0.7" }, @@ -5527,7 +6153,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -5542,7 +6167,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -5557,7 +6181,6 @@ "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, "dependencies": { "which-typed-array": "^1.1.14" }, @@ -5572,7 +6195,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, "engines": { "node": ">=10" }, @@ -5584,7 +6206,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -5596,27 +6217,22 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, "peer": true }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "peer": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -5624,25 +6240,43 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, "peer": true }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, "peer": true }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, "dependencies": { "universalify": "^2.0.0" }, @@ -5654,7 +6288,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, "peer": true, "engines": { "node": "*" @@ -5664,7 +6297,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", - "dev": true, "hasInstallScript": true, "dependencies": { "node-addon-api": "^2.0.0", @@ -5675,11 +6307,18 @@ "node": ">=10.0.0" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -5689,7 +6328,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", - "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.9" } @@ -5698,7 +6336,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, "peer": true, "engines": { "node": ">=6" @@ -5708,7 +6345,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, "peer": true, "dependencies": { "prelude-ls": "~1.1.2", @@ -5722,7 +6358,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -5734,42 +6369,40 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true, "peer": true }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true, "peer": true }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true, - "peer": true + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, "peer": true }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -5785,8 +6418,6 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "peer": true, "dependencies": { "get-func-name": "^2.0.1" } @@ -5794,14 +6425,12 @@ "node_modules/lru_map": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==" }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "peer": true, "dependencies": { "yallist": "^4.0.0" @@ -5814,27 +6443,23 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, "peer": true }, "node_modules/markdown-table": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true, "peer": true }, "node_modules/match-all": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz", - "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==", - "dev": true + "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==" }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -5845,7 +6470,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, "engines": { "node": ">= 0.10.0" } @@ -5854,8 +6478,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "peer": true, "engines": { "node": ">= 8" } @@ -5864,15 +6486,12 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", - "dev": true, "peer": true }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "peer": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -5885,7 +6504,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -5894,7 +6512,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -5905,20 +6522,17 @@ "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5930,7 +6544,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -5939,7 +6552,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "peer": true, "dependencies": { "minimist": "^1.2.6" @@ -5952,7 +6564,6 @@ "version": "0.38.5", "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, "dependencies": { "obliterator": "^2.0.0" } @@ -5961,7 +6572,6 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", - "dev": true, "dependencies": { "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", @@ -5996,7 +6606,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, "engines": { "node": ">=6" } @@ -6005,7 +6614,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -6014,7 +6622,6 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, "funding": [ { "type": "individual", @@ -6041,7 +6648,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -6057,7 +6663,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6076,7 +6681,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -6091,7 +6695,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6102,14 +6705,12 @@ "node_modules/mocha/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/mocha/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -6124,7 +6725,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -6139,7 +6739,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -6148,7 +6747,6 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -6162,25 +6760,27 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/murmur-128": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz", "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==", - "dev": true, "dependencies": { "encode-utf8": "^1.0.2", "fmix": "^0.1.0", "imul": "^1.0.0" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, "node_modules/ndjson": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", - "dev": true, "peer": true, "dependencies": { "json-stringify-safe": "^5.0.1", @@ -6199,20 +6799,17 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, "node_modules/node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, "peer": true, "dependencies": { "lodash": "^4.17.21" @@ -6222,7 +6819,6 @@ "version": "4.8.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "dev": true, "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -6233,7 +6829,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, "peer": true, "engines": { "node": ">=12.19" @@ -6243,7 +6838,6 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, "peer": true, "dependencies": { "abbrev": "1" @@ -6256,7 +6850,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6265,7 +6858,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, "peer": true, "dependencies": { "bn.js": "4.11.6", @@ -6280,14 +6872,12 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, "peer": true }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -6297,7 +6887,6 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -6306,7 +6895,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -6315,7 +6903,6 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -6329,17 +6916,74 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/obliterator": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.4.tgz", - "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==", - "dev": true + "integrity": "sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==" }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -6348,7 +6992,6 @@ "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, "peer": true, "dependencies": { "deep-is": "~0.1.3", @@ -6366,14 +7009,12 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", - "dev": true, "peer": true }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6382,7 +7023,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, "dependencies": { "p-try": "^1.0.0" }, @@ -6394,7 +7034,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, "dependencies": { "p-limit": "^1.1.0" }, @@ -6406,7 +7045,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -6421,23 +7059,31 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, "engines": { "node": ">=4" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parse-cache-control": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", - "dev": true, "peer": true }, "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, "engines": { "node": ">=4" } @@ -6446,23 +7092,27 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -6471,8 +7121,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "peer": true, "engines": { "node": "*" } @@ -6481,7 +7129,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -6497,7 +7144,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -6509,7 +7155,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, "peer": true, "engines": { "node": ">=6" @@ -6519,7 +7164,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, "engines": { "node": ">= 0.4" } @@ -6528,23 +7172,20 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, "peer": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "peer": true, + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -6554,14 +7195,12 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, "peer": true }, "node_modules/promise": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dev": true, "peer": true, "dependencies": { "asap": "~2.0.6" @@ -6571,7 +7210,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, "peer": true, "dependencies": { "kleur": "^3.0.3", @@ -6585,15 +7223,12 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, "peer": true }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -6602,7 +7237,6 @@ "version": "6.12.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", - "dev": true, "dependencies": { "side-channel": "^1.0.6" }, @@ -6617,7 +7251,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -6631,14 +7264,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "peer": true + ] }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -6647,7 +7278,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -6662,7 +7292,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6676,7 +7305,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -6688,7 +7316,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, "peer": true, "dependencies": { "resolve": "^1.1.6" @@ -6701,7 +7328,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, "peer": true, "dependencies": { "minimatch": "^3.0.5" @@ -6714,7 +7340,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", - "dev": true, "peer": true, "engines": { "node": ">=6" @@ -6724,7 +7349,6 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "define-properties": "^1.2.1", @@ -6742,7 +7366,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", - "dev": true, "peer": true, "dependencies": { "req-from": "^2.0.0" @@ -6755,7 +7378,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", - "dev": true, "peer": true, "dependencies": { "resolve-from": "^3.0.0" @@ -6768,7 +7390,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6777,7 +7398,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6786,7 +7406,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, "dependencies": { "path-parse": "^1.0.6" }, @@ -6798,7 +7417,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -6808,8 +7426,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "peer": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -6819,7 +7435,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -6831,7 +7446,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -6841,7 +7455,6 @@ "version": "2.2.7", "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, "dependencies": { "bn.js": "^5.2.0" }, @@ -6853,7 +7466,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -6868,7 +7480,6 @@ "url": "https://feross.org/support" } ], - "peer": true, "dependencies": { "queue-microtask": "^1.2.2" } @@ -6877,7 +7488,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "get-intrinsic": "^1.2.4", @@ -6894,14 +7504,12 @@ "node_modules/safe-array-concat/node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -6921,7 +7529,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -6937,14 +7544,12 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sc-istanbul": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, "peer": true, "dependencies": { "abbrev": "1.0.x", @@ -6970,7 +7575,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "peer": true, "dependencies": { "sprintf-js": "~1.0.2" @@ -6980,7 +7584,6 @@ "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "dev": true, "peer": true, "dependencies": { "inflight": "^1.0.4", @@ -6997,7 +7600,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -7007,7 +7609,6 @@ "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, "peer": true, "dependencies": { "argparse": "^1.0.7", @@ -7021,7 +7622,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, "peer": true, "bin": { "esparse": "bin/esparse.js", @@ -7035,14 +7635,12 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", - "dev": true, "peer": true }, "node_modules/sc-istanbul/node_modules/supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, "peer": true, "dependencies": { "has-flag": "^1.0.0" @@ -7054,14 +7652,12 @@ "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" }, "node_modules/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, "hasInstallScript": true, "dependencies": { "elliptic": "^6.5.4", @@ -7076,7 +7672,6 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -7085,7 +7680,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, "dependencies": { "randombytes": "^2.1.0" } @@ -7094,7 +7688,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7111,7 +7704,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -7125,20 +7717,17 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -7151,7 +7740,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, "peer": true, "dependencies": { "charenc": ">= 0.0.1", @@ -7161,11 +7749,29 @@ "node": "*" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, "node_modules/shelljs": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, "peer": true, "dependencies": { "glob": "^7.0.0", @@ -7183,7 +7789,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -7201,15 +7806,12 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, "peer": true }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -7218,7 +7820,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, "peer": true, "dependencies": { "ansi-styles": "^4.0.0", @@ -7236,7 +7837,6 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", - "dev": true, "dependencies": { "command-exists": "^1.2.8", "commander": "3.0.2", @@ -7259,7 +7859,6 @@ "version": "0.30.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0", @@ -7272,7 +7871,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -7281,7 +7879,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -7290,7 +7887,6 @@ "version": "0.4.56", "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.56.tgz", "integrity": "sha512-HgmsA/Gfklm/M8GFbCX/J1qkVH0spXHgALCNZ8fA8x5X+MFdn/8CP2gr5OVyXjXw6RZTPC/Sxl2RUDQOXyNMeA==", - "dev": true, "dependencies": { "array.prototype.findlast": "^1.2.2" } @@ -7299,7 +7895,6 @@ "version": "0.8.12", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.12.tgz", "integrity": "sha512-8cOB1PtjnjFRqOgwFiD8DaUsYJtVJ6+YdXQtSZDrLGf8cdhhh8xzTtGzVTGeBf15kTv0v7lYPJlV/az7zLEPJw==", - "dev": true, "peer": true, "dependencies": { "@ethersproject/abi": "^5.0.9", @@ -7333,14 +7928,12 @@ "version": "0.18.0", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==", - "dev": true, "peer": true }, "node_modules/solidity-coverage/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "peer": true, "dependencies": { "color-convert": "^1.9.0" @@ -7353,7 +7946,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "peer": true, "dependencies": { "ansi-styles": "^3.2.1", @@ -7368,7 +7960,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "peer": true, "dependencies": { "color-name": "1.1.3" @@ -7378,14 +7969,12 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, "peer": true }, "node_modules/solidity-coverage/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "peer": true, "engines": { "node": ">=0.8.0" @@ -7395,7 +7984,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, "peer": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -7410,7 +7998,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "peer": true, "engines": { "node": ">=4" @@ -7420,7 +8007,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -7430,7 +8016,6 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, "peer": true, "dependencies": { "lru-cache": "^6.0.0" @@ -7446,7 +8031,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "peer": true, "dependencies": { "has-flag": "^3.0.0" @@ -7459,7 +8043,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "peer": true, "engines": { "node": ">= 4.0.0" @@ -7469,7 +8052,6 @@ "version": "0.6.0-beta.36", "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.36.tgz", "integrity": "sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==", - "dev": true, "dependencies": { "handlebars": "^4.7.7", "solidity-ast": "^0.4.38" @@ -7482,7 +8064,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, "optional": true, "peer": true, "dependencies": { @@ -7496,7 +8077,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -7506,7 +8086,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7515,7 +8094,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, "peer": true, "dependencies": { "readable-stream": "^3.0.0" @@ -7525,14 +8103,12 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, "peer": true }, "node_modules/stacktrace-parser": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz", "integrity": "sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==", - "dev": true, "dependencies": { "type-fest": "^0.7.1" }, @@ -7544,7 +8120,6 @@ "version": "0.7.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, "engines": { "node": ">=8" } @@ -7553,7 +8128,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -7562,7 +8136,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -7571,14 +8144,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", - "dev": true, "peer": true }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7592,7 +8163,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7610,7 +8180,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7624,7 +8193,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -7641,7 +8209,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7649,11 +8216,18 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, "node_modules/strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, "dependencies": { "is-hex-prefixed": "1.0.0" }, @@ -7666,7 +8240,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "engines": { "node": ">=8" }, @@ -7678,7 +8251,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7686,11 +8258,21 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/sync-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dev": true, "peer": true, "dependencies": { "http-response-object": "^3.0.1", @@ -7705,7 +8287,6 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dev": true, "peer": true, "dependencies": { "get-port": "^3.1.0" @@ -7715,7 +8296,6 @@ "version": "6.8.2", "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", - "dev": true, "peer": true, "dependencies": { "ajv": "^8.0.1", @@ -7732,7 +8312,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", - "dev": true, "peer": true, "dependencies": { "array-back": "^4.0.1", @@ -7748,7 +8327,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, "peer": true, "engines": { "node": ">=8" @@ -7758,17 +8336,20 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, "peer": true, "engines": { "node": ">=8" } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, "node_modules/then-request": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dev": true, "peer": true, "dependencies": { "@types/concat-stream": "^1.6.0", @@ -7791,14 +8372,12 @@ "version": "8.10.66", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", - "dev": true, "peer": true }, "node_modules/then-request/node_modules/form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, "peer": true, "dependencies": { "asynckit": "^0.4.0", @@ -7813,7 +8392,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, "peer": true, "dependencies": { "readable-stream": "3" @@ -7823,7 +8401,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "dependencies": { "os-tmpdir": "~1.0.2" }, @@ -7835,7 +8412,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -7847,16 +8423,25 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "engines": { "node": ">=0.6" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-command-line-args": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", - "dev": true, "peer": true, "dependencies": { "chalk": "^4.1.0", @@ -7872,7 +8457,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", - "dev": true, "peer": true, "peerDependencies": { "typescript": ">=3.7.0" @@ -7882,7 +8466,6 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -7926,42 +8509,47 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, "peer": true, "engines": { "node": ">=0.3.1" } }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true, "peer": true }, "node_modules/tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", - "dev": true + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" }, "node_modules/tweetnacl": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" }, "node_modules/tweetnacl-util": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true + "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, "peer": true, "dependencies": { "prelude-ls": "~1.1.2" @@ -7974,8 +8562,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "peer": true, "engines": { "node": ">=4" } @@ -7984,7 +8570,6 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "engines": { "node": ">=10" }, @@ -7996,7 +8581,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", - "dev": true, "peer": true, "dependencies": { "@types/prettier": "^2.1.1", @@ -8021,7 +8605,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, "peer": true, "dependencies": { "graceful-fs": "^4.1.2", @@ -8036,7 +8619,6 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, "peer": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -8057,7 +8639,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, "peer": true, "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -8067,7 +8648,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "peer": true, "bin": { "mkdirp": "bin/cmd.js" @@ -8076,11 +8656,25 @@ "node": ">=10" } }, + "node_modules/typechain/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/typechain/node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "peer": true, "engines": { "node": ">= 4.0.0" @@ -8090,7 +8684,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -8104,7 +8697,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -8123,7 +8715,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -8143,7 +8734,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, "dependencies": { "call-bind": "^1.0.7", "for-each": "^0.3.3", @@ -8163,14 +8753,12 @@ "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, "peer": true }, "node_modules/typescript": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", - "dev": true, "peer": true, "bin": { "tsc": "bin/tsc", @@ -8184,7 +8772,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, "peer": true, "engines": { "node": ">=8" @@ -8194,7 +8781,6 @@ "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -8207,7 +8793,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -8222,7 +8807,6 @@ "version": "5.28.4", "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dev": true, "dependencies": { "@fastify/busboy": "^2.0.0" }, @@ -8233,14 +8817,12 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, "engines": { "node": ">= 10.0.0" } @@ -8249,7 +8831,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, "engines": { "node": ">= 0.8" } @@ -8258,8 +8839,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -8268,20 +8847,17 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true, "peer": true }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, "bin": { "uuid": "dist/bin/uuid" } @@ -8290,14 +8866,12 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, "peer": true }, "node_modules/web3-utils": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", - "dev": true, "peer": true, "dependencies": { "@ethereumjs/util": "^8.1.0", @@ -8317,7 +8891,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.3.0.tgz", "integrity": "sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==", - "dev": true, "peer": true, "dependencies": { "@noble/hashes": "1.3.3" @@ -8330,7 +8903,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "dev": true, "peer": true, "engines": { "node": ">= 16" @@ -8343,7 +8915,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.1.3.tgz", "integrity": "sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==", - "dev": true, "peer": true, "dependencies": { "@noble/curves": "1.3.0", @@ -8356,7 +8927,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "peer": true, "dependencies": { "isexe": "^2.0.0" @@ -8369,7 +8939,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -8385,7 +8954,6 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", @@ -8404,7 +8972,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, "dependencies": { "string-width": "^4.0.0" }, @@ -8416,8 +8983,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -8425,14 +8990,12 @@ "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, "node_modules/wordwrapjs": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", - "dev": true, "peer": true, "dependencies": { "reduce-flatten": "^2.0.0", @@ -8446,7 +9009,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", - "dev": true, "peer": true, "engines": { "node": ">=8" @@ -8455,14 +9017,12 @@ "node_modules/workerpool": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==" }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8478,14 +9038,12 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "dev": true, "peer": true, "engines": { "node": ">=10.0.0" @@ -8507,7 +9065,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -8516,14 +9073,12 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "peer": true }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -8541,7 +9096,6 @@ "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, "engines": { "node": ">=10" } @@ -8550,7 +9104,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -8565,7 +9118,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, "peer": true, "engines": { "node": ">=6" @@ -8575,7 +9127,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, @@ -8587,7 +9138,6 @@ "version": "5.7.0", "resolved": "https://registry.npmjs.org/zksync-ethers/-/zksync-ethers-5.7.0.tgz", "integrity": "sha512-X99c5APICTlRzyXXjfwkEjRzOPp3Jwo62+z2DVGaZbe+b9Apbizcd2UGV4NGomoAR2GXPbeiSqi1cf3Hbo3cQw==", - "dev": true, "dependencies": { "ethers": "~5.7.0" }, @@ -8602,7 +9152,6 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, "funding": [ { "type": "individual", diff --git a/package.json b/package.json index 7a7fce94..55e0d734 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,10 @@ "url": "git+https://github.com/decentdao/fractal-contracts.git" }, "scripts": { + "lint": "eslint . --ext .ts --fix", + "lint:check": "eslint . --ext .ts", + "pretty": "prettier . --write", + "pretty:check": "prettier . --check", "clean": "hardhat clean", "compile": "hardhat compile", "docgen": "hardhat docgen", @@ -25,16 +29,25 @@ "bugs": { "url": "https://github.com/decentdao/fractal-contracts/issues" }, - "devDependencies": { + "dependencies": { "@gnosis.pm/zodiac": "^1.1.4", + "@nomicfoundation/hardhat-ethers": "^3.0.5", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0", "@prb/math": "^4.0.3", + "@typescript-eslint/eslint-plugin": "^7.0.0", + "@typescript-eslint/parser": "^7.0.0", + "chai": "^4.2.0", "dotenv": "^16.4.5", + "eslint": "^8.22.0", + "eslint-config-airbnb-typescript": "^18.0.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", "hardhat": "^2.22.2", "hardhat-dependency-compiler": "^1.1.4", "hardhat-deploy": "^0.12.2", + "prettier": "^3.3.3", "solidity-docgen": "^0.6.0-beta.36" } } From 11c995d4c1e4c2ca2343b1bf0b9305b54f8de574 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 22 Oct 2024 11:09:59 -0400 Subject: [PATCH 108/206] Lint and Pretty all the things --- .github/SECURITY.md | 2 +- .github/workflows/publish.yml | 4 +- .github/workflows/tests.yml | 2 +- deploy/core/001_deploy_ERC20Claim.ts | 8 +- deploy/core/002_deploy_FractalModule.ts | 8 +- deploy/core/003_deploy_FractalRegistry.ts | 10 +- deploy/core/004_deploy_ERC20FreezeVoting.ts | 8 +- .../core/005_deploy_MultisigFreezeVoting.ts | 8 +- deploy/core/006_deploy_MultisigFreezeGuard.ts | 8 +- deploy/core/007_deploy_AzoriusFreezeGuard.ts | 8 +- deploy/core/008_deploy_Azorius.ts | 10 +- deploy/core/009_deploy_VotesERC20.ts | 8 +- deploy/core/010_deploy_LinearERC20Voting.ts | 10 +- deploy/core/011_deploy_ModuleProxyFactory.ts | 2 +- deploy/core/012_deploy_KeyValuePairs.ts | 8 +- deploy/core/013_deploy_VotesERC20Wrapper.ts | 8 +- .../014_deploy_LinearERC20WrappedVoting.ts | 10 +- deploy/core/015_deploy_LinearERC721Voting.ts | 8 +- deploy/core/016_deploy_ERC721FreezeVoting.ts | 8 +- deploy/core/017_deploy_DecentHats_0_1_0.ts | 8 +- ...18_deploy_DecentSablierStreamManagement.ts | 8 +- deploy/helpers/deployNonUpgradeable.ts | 4 +- hardhat.config.ts | 57 +- test/Atomic-Deployment.test.ts | 493 +++---- test/Azorius-LinearERC20Voting.test.ts | 1170 ++++++----------- test/Azorius-LinearERC721Voting.test.ts | 824 ++++-------- ...oriusFreezeGuard-ERC20FreezeVoting.test.ts | 543 ++++---- ...usFreezeGuard-MultisigFreezeVoting.test.ts | 526 ++++---- test/DecentHats_0_1_0.test.ts | 541 ++++---- test/DecentSablierStreamManagement.test.ts | 361 +++-- test/ERC20-Claim.test.ts | 239 ++-- test/Fractal-Module.test.ts | 255 ++-- test/Fractal-Registry.test.ts | 58 +- test/GlobalSafeDeployments.test.ts | 8 +- ...tisigFreezeGuard-ERC20FreezeVoting.test.ts | 390 +++--- ...isigFreezeGuard-ERC721FreezeVoting.test.ts | 462 +++---- ...igFreezeGuard-MultisigFreezeVoting.test.ts | 489 ++++--- test/helpers.ts | 176 ++- test/time.ts | 10 +- 39 files changed, 2732 insertions(+), 4028 deletions(-) diff --git a/.github/SECURITY.md b/.github/SECURITY.md index bcd55432..d9c81415 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -19,4 +19,4 @@ Please include the following information in your email: If you prefer secure communication, please use the following GPG key: -https://keys.openpgp.org/search?q=security%40decent-dao.org \ No newline at end of file +https://keys.openpgp.org/search?q=security%40decent-dao.org diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7dfec4bd..d02b6fbd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,8 +12,8 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version-file: ".nvmrc" - registry-url: "https://registry.npmjs.org" + node-version-file: '.nvmrc' + registry-url: 'https://registry.npmjs.org' - run: npm clean-install - run: npm publish env: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8fd3cf7a..d687857c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version-file: ".nvmrc" + node-version-file: '.nvmrc' - run: npm install - run: npm run compile - run: npm run test diff --git a/deploy/core/001_deploy_ERC20Claim.ts b/deploy/core/001_deploy_ERC20Claim.ts index fb32acc0..b3654d3c 100644 --- a/deploy/core/001_deploy_ERC20Claim.ts +++ b/deploy/core/001_deploy_ERC20Claim.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "ERC20Claim", []); + await deployNonUpgradeable(hre, 'ERC20Claim', []); }; export default func; diff --git a/deploy/core/002_deploy_FractalModule.ts b/deploy/core/002_deploy_FractalModule.ts index a14f30ad..de8e0b58 100644 --- a/deploy/core/002_deploy_FractalModule.ts +++ b/deploy/core/002_deploy_FractalModule.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "FractalModule", []); + await deployNonUpgradeable(hre, 'FractalModule', []); }; export default func; diff --git a/deploy/core/003_deploy_FractalRegistry.ts b/deploy/core/003_deploy_FractalRegistry.ts index 64eb718d..2a01c648 100644 --- a/deploy/core/003_deploy_FractalRegistry.ts +++ b/deploy/core/003_deploy_FractalRegistry.ts @@ -1,11 +1,11 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "FractalRegistry", []); + await deployNonUpgradeable(hre, 'FractalRegistry', []); }; -func.tags = ["FractalRegistry"]; +func.tags = ['FractalRegistry']; export default func; diff --git a/deploy/core/004_deploy_ERC20FreezeVoting.ts b/deploy/core/004_deploy_ERC20FreezeVoting.ts index 5b6e2d75..d84e00e7 100644 --- a/deploy/core/004_deploy_ERC20FreezeVoting.ts +++ b/deploy/core/004_deploy_ERC20FreezeVoting.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "ERC20FreezeVoting", []); + await deployNonUpgradeable(hre, 'ERC20FreezeVoting', []); }; export default func; diff --git a/deploy/core/005_deploy_MultisigFreezeVoting.ts b/deploy/core/005_deploy_MultisigFreezeVoting.ts index a1876c4c..de7df8b3 100644 --- a/deploy/core/005_deploy_MultisigFreezeVoting.ts +++ b/deploy/core/005_deploy_MultisigFreezeVoting.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "MultisigFreezeVoting", []); + await deployNonUpgradeable(hre, 'MultisigFreezeVoting', []); }; export default func; diff --git a/deploy/core/006_deploy_MultisigFreezeGuard.ts b/deploy/core/006_deploy_MultisigFreezeGuard.ts index 0ff837db..7b6c4a25 100644 --- a/deploy/core/006_deploy_MultisigFreezeGuard.ts +++ b/deploy/core/006_deploy_MultisigFreezeGuard.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "MultisigFreezeGuard", []); + await deployNonUpgradeable(hre, 'MultisigFreezeGuard', []); }; export default func; diff --git a/deploy/core/007_deploy_AzoriusFreezeGuard.ts b/deploy/core/007_deploy_AzoriusFreezeGuard.ts index 911f520d..89c4f466 100644 --- a/deploy/core/007_deploy_AzoriusFreezeGuard.ts +++ b/deploy/core/007_deploy_AzoriusFreezeGuard.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "AzoriusFreezeGuard", []); + await deployNonUpgradeable(hre, 'AzoriusFreezeGuard', []); }; export default func; diff --git a/deploy/core/008_deploy_Azorius.ts b/deploy/core/008_deploy_Azorius.ts index ac92807b..2b929dfc 100644 --- a/deploy/core/008_deploy_Azorius.ts +++ b/deploy/core/008_deploy_Azorius.ts @@ -1,11 +1,11 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "Azorius", []); + await deployNonUpgradeable(hre, 'Azorius', []); }; -func.tags = ["Azorius"]; +func.tags = ['Azorius']; export default func; diff --git a/deploy/core/009_deploy_VotesERC20.ts b/deploy/core/009_deploy_VotesERC20.ts index dfce6a8b..0aa38973 100644 --- a/deploy/core/009_deploy_VotesERC20.ts +++ b/deploy/core/009_deploy_VotesERC20.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "VotesERC20", []); + await deployNonUpgradeable(hre, 'VotesERC20', []); }; export default func; diff --git a/deploy/core/010_deploy_LinearERC20Voting.ts b/deploy/core/010_deploy_LinearERC20Voting.ts index c746864c..3c511130 100644 --- a/deploy/core/010_deploy_LinearERC20Voting.ts +++ b/deploy/core/010_deploy_LinearERC20Voting.ts @@ -1,16 +1,16 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const chainId = await hre.getChainId(); // See https://github.com/decentdao/decent-contracts/pull/96 - if (chainId === "1" || chainId === "137") { + if (chainId === '1' || chainId === '137') { return; } - await deployNonUpgradeable(hre, "LinearERC20Voting", []); + await deployNonUpgradeable(hre, 'LinearERC20Voting', []); }; export default func; diff --git a/deploy/core/011_deploy_ModuleProxyFactory.ts b/deploy/core/011_deploy_ModuleProxyFactory.ts index 7d2b45e8..52117033 100644 --- a/deploy/core/011_deploy_ModuleProxyFactory.ts +++ b/deploy/core/011_deploy_ModuleProxyFactory.ts @@ -1,5 +1,5 @@ // import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; +import { DeployFunction } from 'hardhat-deploy/types'; // import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; const func: DeployFunction = async (/* hre: HardhatRuntimeEnvironment */) => { diff --git a/deploy/core/012_deploy_KeyValuePairs.ts b/deploy/core/012_deploy_KeyValuePairs.ts index b41565e1..3ba7ada5 100644 --- a/deploy/core/012_deploy_KeyValuePairs.ts +++ b/deploy/core/012_deploy_KeyValuePairs.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "KeyValuePairs", []); + await deployNonUpgradeable(hre, 'KeyValuePairs', []); }; export default func; diff --git a/deploy/core/013_deploy_VotesERC20Wrapper.ts b/deploy/core/013_deploy_VotesERC20Wrapper.ts index cfa4653f..2c412871 100644 --- a/deploy/core/013_deploy_VotesERC20Wrapper.ts +++ b/deploy/core/013_deploy_VotesERC20Wrapper.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "VotesERC20Wrapper", []); + await deployNonUpgradeable(hre, 'VotesERC20Wrapper', []); }; export default func; diff --git a/deploy/core/014_deploy_LinearERC20WrappedVoting.ts b/deploy/core/014_deploy_LinearERC20WrappedVoting.ts index 4609621f..0194982a 100644 --- a/deploy/core/014_deploy_LinearERC20WrappedVoting.ts +++ b/deploy/core/014_deploy_LinearERC20WrappedVoting.ts @@ -1,16 +1,16 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const chainId = await hre.getChainId(); // See https://github.com/decentdao/decent-contracts/pull/96 - if (chainId === "1" || chainId === "137") { + if (chainId === '1' || chainId === '137') { return; } - await deployNonUpgradeable(hre, "LinearERC20WrappedVoting", []); + await deployNonUpgradeable(hre, 'LinearERC20WrappedVoting', []); }; export default func; diff --git a/deploy/core/015_deploy_LinearERC721Voting.ts b/deploy/core/015_deploy_LinearERC721Voting.ts index 1366f7a7..4aa4266c 100644 --- a/deploy/core/015_deploy_LinearERC721Voting.ts +++ b/deploy/core/015_deploy_LinearERC721Voting.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "LinearERC721Voting", []); + await deployNonUpgradeable(hre, 'LinearERC721Voting', []); }; export default func; diff --git a/deploy/core/016_deploy_ERC721FreezeVoting.ts b/deploy/core/016_deploy_ERC721FreezeVoting.ts index 25a3a038..f656d2e0 100644 --- a/deploy/core/016_deploy_ERC721FreezeVoting.ts +++ b/deploy/core/016_deploy_ERC721FreezeVoting.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "ERC721FreezeVoting", []); + await deployNonUpgradeable(hre, 'ERC721FreezeVoting', []); }; export default func; diff --git a/deploy/core/017_deploy_DecentHats_0_1_0.ts b/deploy/core/017_deploy_DecentHats_0_1_0.ts index 6272efd1..89a6ec97 100644 --- a/deploy/core/017_deploy_DecentHats_0_1_0.ts +++ b/deploy/core/017_deploy_DecentHats_0_1_0.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentHats_0_1_0"); + await deployNonUpgradeable(hre, 'DecentHats_0_1_0'); }; export default func; diff --git a/deploy/core/018_deploy_DecentSablierStreamManagement.ts b/deploy/core/018_deploy_DecentSablierStreamManagement.ts index fb33345a..8e406ced 100644 --- a/deploy/core/018_deploy_DecentSablierStreamManagement.ts +++ b/deploy/core/018_deploy_DecentSablierStreamManagement.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentSablierStreamManagement"); + await deployNonUpgradeable(hre, 'DecentSablierStreamManagement'); }; export default func; diff --git a/deploy/helpers/deployNonUpgradeable.ts b/deploy/helpers/deployNonUpgradeable.ts index 60122576..df1679a6 100644 --- a/deploy/helpers/deployNonUpgradeable.ts +++ b/deploy/helpers/deployNonUpgradeable.ts @@ -1,10 +1,10 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; const deployNonUpgradeable = async ( hre: HardhatRuntimeEnvironment, contractName: string, // eslint-disable-next-line @typescript-eslint/no-explicit-any - args: any[] = [] + args: any[] = [], ): Promise => { const { deployments: { deploy }, diff --git a/hardhat.config.ts b/hardhat.config.ts index 9f896ddf..cb5b060d 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,21 +1,20 @@ -import * as dotenv from "dotenv"; -import { HardhatUserConfig } from "hardhat/config"; -import "@nomicfoundation/hardhat-toolbox"; -import "hardhat-dependency-compiler"; -import "hardhat-deploy"; -import "solidity-docgen"; +import * as dotenv from 'dotenv'; +import { HardhatUserConfig } from 'hardhat/config'; +import '@nomicfoundation/hardhat-toolbox'; +import 'hardhat-dependency-compiler'; +import 'hardhat-deploy'; +import 'solidity-docgen'; dotenv.config(); // first address from `test test test test test test test test test test test junk` -const dummyPrivateKey = - "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; +const dummyPrivateKey = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'; const config: HardhatUserConfig = { solidity: { compilers: [ { - version: "0.8.19", + version: '0.8.19', settings: { optimizer: { enabled: true, @@ -24,7 +23,7 @@ const config: HardhatUserConfig = { }, }, { - version: "0.8.28", + version: '0.8.28', settings: { optimizer: { enabled: true, @@ -36,10 +35,10 @@ const config: HardhatUserConfig = { }, dependencyCompiler: { paths: [ - "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol", - "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol", - "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol", - "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol", + '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol', + '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol', + '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol', + '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol', ], }, namedAccounts: { @@ -55,41 +54,35 @@ const config: HardhatUserConfig = { networks: { mainnet: { chainId: 1, - url: - process.env.MAINNET_PROVIDER || "https://ethereum-rpc.publicnode.com", + url: process.env.MAINNET_PROVIDER || 'https://ethereum-rpc.publicnode.com', accounts: process.env.MAINNET_DEPLOYER_PRIVATE_KEY ? [process.env.MAINNET_DEPLOYER_PRIVATE_KEY] : [dummyPrivateKey], }, sepolia: { chainId: 11155111, - url: - process.env.SEPOLIA_PROVIDER || - "https://ethereum-sepolia-rpc.publicnode.com", + url: process.env.SEPOLIA_PROVIDER || 'https://ethereum-sepolia-rpc.publicnode.com', accounts: process.env.SEPOLIA_DEPLOYER_PRIVATE_KEY ? [process.env.SEPOLIA_DEPLOYER_PRIVATE_KEY] : [dummyPrivateKey], }, polygon: { chainId: 137, - url: - process.env.POLYGON_PROVIDER || - "https://polygon-bor-rpc.publicnode.com", + url: process.env.POLYGON_PROVIDER || 'https://polygon-bor-rpc.publicnode.com', accounts: process.env.POLYGON_DEPLOYER_PRIVATE_KEY ? [process.env.POLYGON_DEPLOYER_PRIVATE_KEY] : [dummyPrivateKey], }, base: { chainId: 8453, - url: process.env.BASE_PROVIDER || "https://base-rpc.publicnode.com", + url: process.env.BASE_PROVIDER || 'https://base-rpc.publicnode.com', accounts: process.env.BASE_DEPLOYER_PRIVATE_KEY ? [process.env.BASE_DEPLOYER_PRIVATE_KEY] : [dummyPrivateKey], }, optimism: { chainId: 10, - url: - process.env.OPTIMISM_PROVIDER || "https://optimism-rpc.publicnode.com", + url: process.env.OPTIMISM_PROVIDER || 'https://optimism-rpc.publicnode.com', accounts: process.env.OPTIMISM_DEPLOYER_PRIVATE_KEY ? [process.env.OPTIMISM_DEPLOYER_PRIVATE_KEY] : [dummyPrivateKey], @@ -97,21 +90,21 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: { - mainnet: process.env.ETHERSCAN_API_KEY || "", - sepolia: process.env.ETHERSCAN_API_KEY || "", - polygon: process.env.POLYGONSCAN_API_KEY || "", - base: process.env.BASESCAN_API_KEY || "", - optimisticEthereum: process.env.OPTIMISTIC_ETHERSCAN_API_KEY || "", + mainnet: process.env.ETHERSCAN_API_KEY || '', + sepolia: process.env.ETHERSCAN_API_KEY || '', + polygon: process.env.POLYGONSCAN_API_KEY || '', + base: process.env.BASESCAN_API_KEY || '', + optimisticEthereum: process.env.OPTIMISTIC_ETHERSCAN_API_KEY || '', }, }, sourcify: { enabled: true, }, paths: { - deploy: "deploy/core", + deploy: 'deploy/core', }, docgen: { - pages: "files", + pages: 'files', }, }; diff --git a/test/Atomic-Deployment.test.ts b/test/Atomic-Deployment.test.ts index 243aaace..51039dd8 100644 --- a/test/Atomic-Deployment.test.ts +++ b/test/Atomic-Deployment.test.ts @@ -1,7 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import hre from "hardhat"; -import { ethers } from "ethers"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { Azorius__factory, FractalModule, @@ -14,23 +13,22 @@ import { MultiSendCallOnly__factory, MultisigFreezeGuard, MultisigFreezeGuard__factory, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, + getMultiSendCallOnly, +} from './GlobalSafeDeployments.test'; import { calculateProxyAddress, predictGnosisSafeAddress, buildContractCall, MetaTransaction, encodeMultiSend, -} from "./helpers"; - -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, - getMultiSendCallOnly, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; -describe("Atomic Gnosis Safe Deployment", () => { +describe('Atomic Gnosis Safe Deployment', () => { // Factories let gnosisSafeProxyFactory: GnosisSafeProxyFactory; @@ -61,9 +59,7 @@ describe("Atomic Gnosis Safe Deployment", () => { const threshold = 2; let predictedFreezeGuard: string; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); @@ -77,13 +73,8 @@ describe("Atomic Gnosis Safe Deployment", () => { // SETUP GnosisSafe createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [ - owner1.address, - owner2.address, - owner3.address, - await multiSendCallOnly.getAddress(), - ], + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ + [owner1.address, owner2.address, owner3.address, await multiSendCallOnly.getAddress()], 1, ethers.ZeroAddress, ethers.ZeroHash, @@ -97,69 +88,50 @@ describe("Atomic Gnosis Safe Deployment", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Get Gnosis Safe contract // eslint-disable-next-line camelcase - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); /// ///////////// GUARD /////////////////// // DEPLOY GUARD - freezeGuardImplementation = await new MultisigFreezeGuard__factory( - deployer - ).deploy(); + freezeGuardImplementation = await new MultisigFreezeGuard__factory(deployer).deploy(); freezeGuardFactoryInit = // eslint-disable-next-line camelcase - MultisigFreezeGuard__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["uint256", "uint256", "address", "address", "address"], - [ - 10, - 20, - owner1.address, - owner1.address, - await gnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeGuard__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'address'], + [10, 20, owner1.address, owner1.address, await gnosisSafe.getAddress()], + ), + ]); predictedFreezeGuard = await calculateProxyAddress( moduleProxyFactory, await freezeGuardImplementation.getAddress(), freezeGuardFactoryInit, - "10031021" + '10031021', ); - freezeGuard = await hre.ethers.getContractAt( - "MultisigFreezeGuard", - predictedFreezeGuard - ); + freezeGuard = await hre.ethers.getContractAt('MultisigFreezeGuard', predictedFreezeGuard); /// /////////////// MODULE //////////////// // DEPLOY Fractal Module - fractalModuleSingleton = await new FractalModule__factory( - deployer - ).deploy(); + fractalModuleSingleton = await new FractalModule__factory(deployer).deploy(); // SETUP Module setModuleCalldata = // eslint-disable-next-line camelcase - FractalModule__factory.createInterface().encodeFunctionData("setUp", [ + FractalModule__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]"], + ['address', 'address', 'address', 'address[]'], [ owner1.address, await gnosisSafe.getAddress(), await gnosisSafe.getAddress(), [owner2.address], - ] + ], ), ]); @@ -167,106 +139,77 @@ describe("Atomic Gnosis Safe Deployment", () => { moduleProxyFactory, await fractalModuleSingleton.getAddress(), setModuleCalldata, - "10031021" + '10031021', ); - fractalModule = await hre.ethers.getContractAt( - "FractalModule", - predictedFractalModule - ); + fractalModule = await hre.ethers.getContractAt('FractalModule', predictedFractalModule); // TX Array sigs = - "0x000000000000000000000000" + + '0x000000000000000000000000' + (await multiSendCallOnly.getAddress()).slice(2) + - "0000000000000000000000000000000000000000000000000000000000000000" + - "01"; + '0000000000000000000000000000000000000000000000000000000000000000' + + '01'; }); - describe("Atomic Gnosis Safe Deployment", () => { - it("Setup Fractal Module w/ ModuleProxyCreationEvent", async () => { + describe('Atomic Gnosis Safe Deployment', () => { + it('Setup Fractal Module w/ ModuleProxyCreationEvent', async () => { const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await fractalModuleSingleton.getAddress(), - setModuleCalldata, - "10031021", - ], + 'deployModule', + [await fractalModuleSingleton.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(moduleProxyFactory, "ModuleProxyCreation") - .withArgs( - predictedFractalModule, - await fractalModuleSingleton.getAddress() - ); + .to.emit(moduleProxyFactory, 'ModuleProxyCreation') + .withArgs(predictedFractalModule, await fractalModuleSingleton.getAddress()); expect(await fractalModule.avatar()).eq(await gnosisSafe.getAddress()); - expect(await fractalModule.getFunction("target")()).eq( - await gnosisSafe.getAddress() - ); + expect(await fractalModule.getFunction('target')()).eq(await gnosisSafe.getAddress()); expect(await fractalModule.owner()).eq(owner1.address); }); - it("Setup FreezeGuard w/ ModuleProxyCreationEvent", async () => { + it('Setup FreezeGuard w/ ModuleProxyCreationEvent', async () => { const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await freezeGuardImplementation.getAddress(), - freezeGuardFactoryInit, - "10031021", - ], + 'deployModule', + [await freezeGuardImplementation.getAddress(), freezeGuardFactoryInit, '10031021'], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(moduleProxyFactory, "ModuleProxyCreation") - .withArgs( - predictedFreezeGuard, - await freezeGuardImplementation.getAddress() - ); + .to.emit(moduleProxyFactory, 'ModuleProxyCreation') + .withArgs(predictedFreezeGuard, await freezeGuardImplementation.getAddress()); expect(await freezeGuard.timelockPeriod()).eq(10); expect(await freezeGuard.freezeVoting()).eq(owner1.address); - expect(await freezeGuard.childGnosisSafe()).eq( - await gnosisSafe.getAddress() - ); + expect(await freezeGuard.childGnosisSafe()).eq(await gnosisSafe.getAddress()); }); - it("Setup Azorius Module w/ ModuleProxyCreationEvent", async () => { + it('Setup Azorius Module w/ ModuleProxyCreationEvent', async () => { const VOTING_STRATEGIES_TO_DEPLOY: string[] = []; const encodedInitAzoriusData = abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ await gnosisSafe.getAddress(), await gnosisSafe.getAddress(), @@ -274,13 +217,11 @@ describe("Atomic Gnosis Safe Deployment", () => { VOTING_STRATEGIES_TO_DEPLOY, 0, 0, - ] + ], ); const encodedSetupAzoriusData = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ - encodedInitAzoriusData, - ]); + Azorius__factory.createInterface().encodeFunctionData('setUp', [encodedInitAzoriusData]); const azoriusSingleton = await new Azorius__factory(deployer).deploy(); @@ -288,37 +229,26 @@ describe("Atomic Gnosis Safe Deployment", () => { moduleProxyFactory, await azoriusSingleton.getAddress(), encodedSetupAzoriusData, - "10031021" + '10031021', ); // eslint-disable-next-line camelcase - const azoriusContract = Azorius__factory.connect( - predictedAzoriusModule, - deployer - ); + const azoriusContract = Azorius__factory.connect(predictedAzoriusModule, deployer); const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await azoriusSingleton.getAddress(), - encodedSetupAzoriusData, - "10031021", - ], + 'deployModule', + [await azoriusSingleton.getAddress(), encodedSetupAzoriusData, '10031021'], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); @@ -326,97 +256,80 @@ describe("Atomic Gnosis Safe Deployment", () => { const tx = await multiSendCallOnly.multiSend(safeTx); await expect(tx) - .to.emit(moduleProxyFactory, "ModuleProxyCreation") + .to.emit(moduleProxyFactory, 'ModuleProxyCreation') .withArgs(predictedAzoriusModule, await azoriusSingleton.getAddress()); expect(await azoriusContract.avatar()).eq(await gnosisSafe.getAddress()); - expect(await azoriusContract.getFunction("target")()).eq( - await gnosisSafe.getAddress() - ); + expect(await azoriusContract.getFunction('target')()).eq(await gnosisSafe.getAddress()); expect(await azoriusContract.owner()).eq(await gnosisSafe.getAddress()); }); - it("Setup Module w/ enabledModule event", async () => { + it('Setup Module w/ enabledModule event', async () => { const internalTxs: MetaTransaction[] = [ await buildContractCall( gnosisSafe, - "enableModule", + 'enableModule', [await fractalModule.getAddress()], 0, - false + false, ), ]; const safeInternalTx = encodeMultiSend(internalTxs); const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await fractalModuleSingleton.getAddress(), - setModuleCalldata, - "10031021", - ], + 'deployModule', + [await fractalModuleSingleton.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await freezeGuardImplementation.getAddress(), - freezeGuardFactoryInit, - "10031021", - ], + 'deployModule', + [await freezeGuardImplementation.getAddress(), freezeGuardFactoryInit, '10031021'], 0, - false + false, ), await buildContractCall( gnosisSafe, - "execTransaction", + 'execTransaction', [ await multiSendCallOnly.getAddress(), // to - "0", // value + '0', // value // eslint-disable-next-line camelcase - MultiSendCallOnly__factory.createInterface().encodeFunctionData( - "multiSend", - [safeInternalTx] - ), // calldata - "1", // operation - "0", // tx gas - "0", // base gas - "0", // gas price + MultiSendCallOnly__factory.createInterface().encodeFunctionData('multiSend', [ + safeInternalTx, + ]), // calldata + '1', // operation + '0', // tx gas + '0', // base gas + '0', // gas price ethers.ZeroAddress, // gas token ethers.ZeroAddress, // receiver sigs, // sigs ], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(gnosisSafe, "EnabledModule") + .to.emit(gnosisSafe, 'EnabledModule') .withArgs(await fractalModule.getAddress()); - expect( - await gnosisSafe.isModuleEnabled(await fractalModule.getAddress()) - ).to.eq(true); + expect(await gnosisSafe.isModuleEnabled(await fractalModule.getAddress())).to.eq(true); }); - it("Setup AzoriusModule w/ enabledModule event", async () => { + it('Setup AzoriusModule w/ enabledModule event', async () => { const VOTING_STRATEGIES_TO_DEPLOY: string[] = []; // @todo pass expected addresses for voting strategies const encodedInitAzoriusData = abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ await gnosisSafe.getAddress(), await gnosisSafe.getAddress(), @@ -424,13 +337,11 @@ describe("Atomic Gnosis Safe Deployment", () => { VOTING_STRATEGIES_TO_DEPLOY, 0, 0, - ] + ], ); const encodedSetupAzoriusData = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ - encodedInitAzoriusData, - ]); + Azorius__factory.createInterface().encodeFunctionData('setUp', [encodedInitAzoriusData]); const azoriusSingleton = await new Azorius__factory(deployer).deploy(); @@ -438,262 +349,206 @@ describe("Atomic Gnosis Safe Deployment", () => { moduleProxyFactory, await azoriusSingleton.getAddress(), encodedSetupAzoriusData, - "10031021" + '10031021', ); // eslint-disable-next-line camelcase - const azoriusContract = Azorius__factory.connect( - predictedAzoriusModule, - deployer - ); + const azoriusContract = Azorius__factory.connect(predictedAzoriusModule, deployer); const internalTxs: MetaTransaction[] = [ await buildContractCall( gnosisSafe, - "enableModule", + 'enableModule', [await fractalModule.getAddress()], 0, - false + false, ), await buildContractCall( gnosisSafe, - "enableModule", + 'enableModule', [await azoriusContract.getAddress()], 0, - false + false, ), ]; const safeInternalTx = encodeMultiSend(internalTxs); const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await fractalModuleSingleton.getAddress(), - setModuleCalldata, - "10031021", - ], + 'deployModule', + [await fractalModuleSingleton.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await freezeGuardImplementation.getAddress(), - freezeGuardFactoryInit, - "10031021", - ], + 'deployModule', + [await freezeGuardImplementation.getAddress(), freezeGuardFactoryInit, '10031021'], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await azoriusSingleton.getAddress(), - encodedSetupAzoriusData, - "10031021", - ], + 'deployModule', + [await azoriusSingleton.getAddress(), encodedSetupAzoriusData, '10031021'], 0, - false + false, ), await buildContractCall( gnosisSafe, - "execTransaction", + 'execTransaction', [ await multiSendCallOnly.getAddress(), // to - "0", // value + '0', // value // eslint-disable-next-line camelcase - MultiSendCallOnly__factory.createInterface().encodeFunctionData( - "multiSend", - [safeInternalTx] - ), // calldata - "1", // operation - "0", // tx gas - "0", // base gas - "0", // gas price + MultiSendCallOnly__factory.createInterface().encodeFunctionData('multiSend', [ + safeInternalTx, + ]), // calldata + '1', // operation + '0', // tx gas + '0', // base gas + '0', // gas price ethers.ZeroAddress, // gas token ethers.ZeroAddress, // receiver sigs, // sigs ], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(gnosisSafe, "EnabledModule") + .to.emit(gnosisSafe, 'EnabledModule') .withArgs(await azoriusContract.getAddress()); - expect( - await gnosisSafe.isModuleEnabled(await azoriusContract.getAddress()) - ).to.eq(true); + expect(await gnosisSafe.isModuleEnabled(await azoriusContract.getAddress())).to.eq(true); }); - it("Setup Guard w/ changeGuard event", async () => { + it('Setup Guard w/ changeGuard event', async () => { const internalTxs: MetaTransaction[] = [ - await buildContractCall( - gnosisSafe, - "setGuard", - [await freezeGuard.getAddress()], - 0, - false - ), + await buildContractCall(gnosisSafe, 'setGuard', [await freezeGuard.getAddress()], 0, false), ]; const safeInternalTx = encodeMultiSend(internalTxs); const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await fractalModuleSingleton.getAddress(), - setModuleCalldata, - "10031021", - ], + 'deployModule', + [await fractalModuleSingleton.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await freezeGuardImplementation.getAddress(), - freezeGuardFactoryInit, - "10031021", - ], + 'deployModule', + [await freezeGuardImplementation.getAddress(), freezeGuardFactoryInit, '10031021'], 0, - false + false, ), await buildContractCall( gnosisSafe, - "execTransaction", + 'execTransaction', [ await multiSendCallOnly.getAddress(), // to - "0", // value + '0', // value // eslint-disable-next-line camelcase - MultiSendCallOnly__factory.createInterface().encodeFunctionData( - "multiSend", - [safeInternalTx] - ), // calldata - "1", // operation - "0", // tx gas - "0", // base gas - "0", // gas price + MultiSendCallOnly__factory.createInterface().encodeFunctionData('multiSend', [ + safeInternalTx, + ]), // calldata + '1', // operation + '0', // tx gas + '0', // base gas + '0', // gas price ethers.ZeroAddress, // gas token ethers.ZeroAddress, // receiver sigs, // sigs ], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(gnosisSafe, "ChangedGuard") + .to.emit(gnosisSafe, 'ChangedGuard') .withArgs(await freezeGuard.getAddress()); }); - it("Setup Gnosis Safe w/ removedOwner event", async () => { + it('Setup Gnosis Safe w/ removedOwner event', async () => { const internalTxs: MetaTransaction[] = [ await buildContractCall( gnosisSafe, - "removeOwner", + 'removeOwner', [owner3.address, await multiSendCallOnly.getAddress(), threshold], 0, - false + false, ), ]; const safeInternalTx = encodeMultiSend(internalTxs); const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await fractalModuleSingleton.getAddress(), - setModuleCalldata, - "10031021", - ], + 'deployModule', + [await fractalModuleSingleton.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [ - await freezeGuardImplementation.getAddress(), - freezeGuardFactoryInit, - "10031021", - ], + 'deployModule', + [await freezeGuardImplementation.getAddress(), freezeGuardFactoryInit, '10031021'], 0, - false + false, ), await buildContractCall( gnosisSafe, - "execTransaction", + 'execTransaction', [ await multiSendCallOnly.getAddress(), // to - "0", // value + '0', // value // eslint-disable-next-line camelcase - MultiSendCallOnly__factory.createInterface().encodeFunctionData( - "multiSend", - [safeInternalTx] - ), // calldata - "1", // operation - "0", // tx gas - "0", // base gas - "0", // gas price + MultiSendCallOnly__factory.createInterface().encodeFunctionData('multiSend', [ + safeInternalTx, + ]), // calldata + '1', // operation + '0', // tx gas + '0', // base gas + '0', // gas price ethers.ZeroAddress, // gas token ethers.ZeroAddress, // receiver sigs, // sigs ], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(gnosisSafe, "RemovedOwner") + .to.emit(gnosisSafe, 'RemovedOwner') .withArgs(await multiSendCallOnly.getAddress()); expect(await gnosisSafe.isOwner(owner1.address)).eq(true); expect(await gnosisSafe.isOwner(owner2.address)).eq(true); expect(await gnosisSafe.isOwner(owner3.address)).eq(true); - expect(await gnosisSafe.isOwner(await multiSendCallOnly.getAddress())).eq( - false - ); + expect(await gnosisSafe.isOwner(await multiSendCallOnly.getAddress())).eq(false); expect(await gnosisSafe.getThreshold()).eq(threshold); }); }); diff --git a/test/Azorius-LinearERC20Voting.test.ts b/test/Azorius-LinearERC20Voting.test.ts index 8840f3b2..3abc55ec 100644 --- a/test/Azorius-LinearERC20Voting.test.ts +++ b/test/Azorius-LinearERC20Voting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import hre from "hardhat"; -import { ethers } from "ethers"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { GnosisSafe, @@ -17,23 +15,23 @@ import { VotesERC20__factory, ModuleProxyFactory, GnosisSafeL2__factory, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, safeSignTypedData, predictGnosisSafeAddress, calculateProxyAddress, -} from "./helpers"; - -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; +import time from './time'; -describe("Safe with Azorius module and linearERC20Voting", () => { +describe('Safe with Azorius module and linearERC20Voting', () => { // Deployed contracts let gnosisSafe: GnosisSafe; let azorius: Azorius; @@ -58,9 +56,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Gnosis let createGnosisSetupCalldata: string; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); @@ -82,19 +78,19 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Get Gnosis Safe Proxy factory gnosisSafeProxyFactory = await hre.ethers.getContractAt( - "GnosisSafeProxyFactory", - await gnosisSafeProxyFactory.getAddress() + 'GnosisSafeProxyFactory', + await gnosisSafeProxyFactory.getAddress(), ); // Get module proxy factory moduleProxyFactory = await hre.ethers.getContractAt( - "ModuleProxyFactory", - await moduleProxyFactory.getAddress() + 'ModuleProxyFactory', + await moduleProxyFactory.getAddress(), ); createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ [gnosisSafeOwner.address], 1, ethers.ZeroAddress, @@ -109,32 +105,29 @@ describe("Safe with Azorius module and linearERC20Voting", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, - saltNum + saltNum, ); - gnosisSafe = await hre.ethers.getContractAt( - "GnosisSafe", - predictedGnosisSafeAddress - ); + gnosisSafe = await hre.ethers.getContractAt('GnosisSafe', predictedGnosisSafeAddress); // Deploy Votes ERC-20 mastercopy contract votesERC20Mastercopy = await new VotesERC20__factory(deployer).deploy(); const votesERC20SetupCalldata = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "DCNT", - "DCNT", + 'DCNT', + 'DCNT', [ tokenHolder1.address, tokenHolder2.address, @@ -142,27 +135,24 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await gnosisSafe.getAddress(), ], [100, 200, 300, 600], - ] + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), votesERC20SetupCalldata, - "10031021" + '10031021', ); const predictedVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), votesERC20SetupCalldata, - "10031021" + '10031021', ); - votesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedVotesERC20Address - ); + votesERC20 = await hre.ethers.getContractAt('VotesERC20', predictedVotesERC20Address); // Token holders delegate votes // Token holder 1 delegates to token holder 2, so final vote counts should be: @@ -178,9 +168,9 @@ describe("Safe with Azorius module and linearERC20Voting", () => { const azoriusSetupCalldata = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ + Azorius__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ gnosisSafeOwner.address, await gnosisSafe.getAddress(), @@ -188,46 +178,33 @@ describe("Safe with Azorius module and linearERC20Voting", () => { [], 60, // timelock period in blocks 60, // execution period in blocks - ] + ], ), ]); await moduleProxyFactory.deployModule( await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); const predictedAzoriusAddress = await calculateProxyAddress( moduleProxyFactory, await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); - azorius = await hre.ethers.getContractAt( - "Azorius", - predictedAzoriusAddress - ); + azorius = await hre.ethers.getContractAt('Azorius', predictedAzoriusAddress); // Deploy Linear ERC20 Voting Mastercopy - linearERC20VotingMastercopy = await new LinearERC20Voting__factory( - deployer - ).deploy(); + linearERC20VotingMastercopy = await new LinearERC20Voting__factory(deployer).deploy(); const linearERC20VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC20Voting__factory.createInterface().encodeFunctionData("setUp", [ + LinearERC20Voting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - [ - "address", - "address", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], + ['address', 'address', 'address', 'uint32', 'uint256', 'uint256', 'uint256'], [ gnosisSafeOwner.address, // owner await votesERC20.getAddress(), // governance token @@ -236,38 +213,35 @@ describe("Safe with Azorius module and linearERC20Voting", () => { 300, // proposer weight 500000, // quorom numerator, denominator is 1,000,000, so quorum percentage is 50% 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] + ], ), ]); await moduleProxyFactory.deployModule( await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" + '10031021', ); const predictedLinearERC20VotingAddress = await calculateProxyAddress( moduleProxyFactory, await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" + '10031021', ); linearERC20Voting = await hre.ethers.getContractAt( - "LinearERC20Voting", - predictedLinearERC20VotingAddress + 'LinearERC20Voting', + predictedLinearERC20VotingAddress, ); // Enable the Linear Voting strategy on Azorius - await azorius - .connect(gnosisSafeOwner) - .enableStrategy(await linearERC20Voting.getAddress()); + await azorius.connect(gnosisSafeOwner).enableStrategy(await linearERC20Voting.getAddress()); // Create transaction on Gnosis Safe to setup Azorius module - const enableAzoriusModuleData = gnosisSafe.interface.encodeFunctionData( - "enableModule", - [await azorius.getAddress()] - ); + const enableAzoriusModuleData = gnosisSafe.interface.encodeFunctionData('enableModule', [ + await azorius.getAddress(), + ]); const enableAzoriusModuleTx = buildSafeTransaction({ to: await gnosisSafe.getAddress(), @@ -276,13 +250,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { nonce: await gnosisSafe.nonce(), }); - const sigs = [ - await safeSignTypedData( - gnosisSafeOwner, - gnosisSafe, - enableAzoriusModuleTx - ), - ]; + const sigs = [await safeSignTypedData(gnosisSafeOwner, gnosisSafe, enableAzoriusModuleTx)]; const signatureBytes = buildSignatureBytes(sigs); @@ -298,67 +266,48 @@ describe("Safe with Azorius module and linearERC20Voting", () => { enableAzoriusModuleTx.gasPrice, enableAzoriusModuleTx.gasToken, enableAzoriusModuleTx.refundReceiver, - signatureBytes - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); // Gnosis Safe received the 1,000 tokens - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); }); - describe("Safe with Azorius module and linearERC20Voting", () => { - it("Gets correctly initialized", async () => { + describe('Safe with Azorius module and linearERC20Voting', () => { + it('Gets correctly initialized', async () => { expect(await linearERC20Voting.owner()).to.eq(gnosisSafeOwner.address); - expect(await linearERC20Voting.governanceToken()).to.eq( - await votesERC20.getAddress() - ); - expect(await linearERC20Voting.azoriusModule()).to.eq( - await azorius.getAddress() - ); + expect(await linearERC20Voting.governanceToken()).to.eq(await votesERC20.getAddress()); + expect(await linearERC20Voting.azoriusModule()).to.eq(await azorius.getAddress()); expect(await linearERC20Voting.votingPeriod()).to.eq(60); expect(await linearERC20Voting.quorumNumerator()).to.eq(500000); }); - it("A strategy cannot be enabled more than once", async () => { + it('A strategy cannot be enabled more than once', async () => { await expect( - azorius - .connect(gnosisSafeOwner) - .enableStrategy(await linearERC20Voting.getAddress()) - ).to.be.revertedWithCustomError(azorius, "StrategyEnabled()"); + azorius.connect(gnosisSafeOwner).enableStrategy(await linearERC20Voting.getAddress()), + ).to.be.revertedWithCustomError(azorius, 'StrategyEnabled()'); }); - it("An invalid strategy cannot be enabled", async () => { + it('An invalid strategy cannot be enabled', async () => { await expect( - azorius.connect(gnosisSafeOwner).enableStrategy(ethers.ZeroAddress) - ).to.be.revertedWithCustomError(azorius, "InvalidStrategy"); + azorius.connect(gnosisSafeOwner).enableStrategy(ethers.ZeroAddress), + ).to.be.revertedWithCustomError(azorius, 'InvalidStrategy'); }); - it("An invalid strategy cannot be disabled", async () => { + it('An invalid strategy cannot be disabled', async () => { await expect( - azorius - .connect(gnosisSafeOwner) - .disableStrategy(ethers.ZeroAddress, ethers.ZeroAddress) - ).to.be.revertedWithCustomError(azorius, "InvalidStrategy"); + azorius.connect(gnosisSafeOwner).disableStrategy(ethers.ZeroAddress, ethers.ZeroAddress), + ).to.be.revertedWithCustomError(azorius, 'InvalidStrategy'); }); - it("Multiple strategies can be enabled, disabled, and returned", async () => { - await azorius - .connect(gnosisSafeOwner) - .enableStrategy(mockStrategy1.address); + it('Multiple strategies can be enabled, disabled, and returned', async () => { + await azorius.connect(gnosisSafeOwner).enableStrategy(mockStrategy1.address); - await azorius - .connect(gnosisSafeOwner) - .enableStrategy(mockStrategy2.address); + await azorius.connect(gnosisSafeOwner).enableStrategy(mockStrategy2.address); expect( - ( - await azorius.getStrategies( - "0x0000000000000000000000000000000000000001", - 3 - ) - )._strategies + (await azorius.getStrategies('0x0000000000000000000000000000000000000001', 3))._strategies, ).to.deep.eq([ mockStrategy2.address, mockStrategy1.address, @@ -370,84 +319,72 @@ describe("Safe with Azorius module and linearERC20Voting", () => { .disableStrategy(mockStrategy2.address, mockStrategy1.address); expect( - ( - await azorius.getStrategies( - "0x0000000000000000000000000000000000000001", - 3 - ) - )._strategies - ).to.deep.eq([ - mockStrategy2.address, - await linearERC20Voting.getAddress(), - ]); + (await azorius.getStrategies('0x0000000000000000000000000000000000000001', 3))._strategies, + ).to.deep.eq([mockStrategy2.address, await linearERC20Voting.getAddress()]); }); - it("An invalid strategy cannot be disabled", async () => { + it('An invalid strategy cannot be disabled', async () => { await expect( - azorius - .connect(gnosisSafeOwner) - .disableStrategy(ethers.ZeroAddress, mockStrategy2.address) - ).to.be.revertedWithCustomError(azorius, "StrategyDisabled"); + azorius.connect(gnosisSafeOwner).disableStrategy(ethers.ZeroAddress, mockStrategy2.address), + ).to.be.revertedWithCustomError(azorius, 'StrategyDisabled'); }); - it("The owner can change the Azorius Module on the Strategy", async () => { - await linearERC20Voting - .connect(gnosisSafeOwner) - .setAzorius(deployer.address); + it('The owner can change the Azorius Module on the Strategy', async () => { + await linearERC20Voting.connect(gnosisSafeOwner).setAzorius(deployer.address); expect(await linearERC20Voting.azoriusModule()).to.eq(deployer.address); }); - it("A non-owner cannot change the Azorius Module on the Strategy", async () => { + it('A non-owner cannot change the Azorius Module on the Strategy', async () => { await expect( - linearERC20Voting.connect(tokenHolder1).setAzorius(deployer.address) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC20Voting.connect(tokenHolder1).setAzorius(deployer.address), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("The owner can update the voting period", async () => { + it('The owner can update the voting period', async () => { expect(await linearERC20Voting.votingPeriod()).to.eq(60); await linearERC20Voting.connect(gnosisSafeOwner).updateVotingPeriod(120); expect(await linearERC20Voting.votingPeriod()).to.eq(120); }); - it("A non-owner cannot update the strategy voting period", async () => { + it('A non-owner cannot update the strategy voting period', async () => { await expect( - linearERC20Voting.connect(tokenHolder1).updateVotingPeriod(120) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC20Voting.connect(tokenHolder1).updateVotingPeriod(120), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("The owner can update the timelock period", async () => { + it('The owner can update the timelock period', async () => { expect(await azorius.timelockPeriod()).to.eq(60); await azorius.connect(gnosisSafeOwner).updateTimelockPeriod(120); expect(await azorius.timelockPeriod()).to.eq(120); }); - it("A non-owner cannot update the strategy timelock period", async () => { - await expect( - azorius.connect(tokenHolder1).updateTimelockPeriod(120) - ).to.be.revertedWith("Ownable: caller is not the owner"); + it('A non-owner cannot update the strategy timelock period', async () => { + await expect(azorius.connect(tokenHolder1).updateTimelockPeriod(120)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Getting proposal state on an invalid proposal ID reverts", async () => { + it('Getting proposal state on an invalid proposal ID reverts', async () => { await expect(azorius.proposalState(0)).to.be.revertedWithCustomError( azorius, - "InvalidProposal" + 'InvalidProposal', ); await expect(azorius.proposalState(0)).to.be.revertedWithCustomError( azorius, - "InvalidProposal" + 'InvalidProposal', ); }); - it("A proposal cannot be submitted if the specified strategy has not been enabled", async () => { + it('A proposal cannot be submitted if the specified strategy has not been enabled', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -460,35 +397,31 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await expect( azorius .connect(tokenHolder2) - .submitProposal( - await votesERC20.getAddress(), - "0x", - [proposalTransaction], - "" - ) - ).to.be.revertedWithCustomError(azorius, "StrategyDisabled"); + .submitProposal(await votesERC20.getAddress(), '0x', [proposalTransaction], ''), + ).to.be.revertedWithCustomError(azorius, 'StrategyDisabled'); }); - it("Proposal cannot be received by the strategy from address other than Azorius", async () => { + it('Proposal cannot be received by the strategy from address other than Azorius', async () => { // Submit call from address that isn't Azorius module - await expect( - linearERC20Voting.initializeProposal("0x") - ).to.be.revertedWithCustomError(linearERC20Voting, "OnlyAzorius"); + await expect(linearERC20Voting.initializeProposal('0x')).to.be.revertedWithCustomError( + linearERC20Voting, + 'OnlyAzorius', + ); }); it("Votes cannot be cast on a proposal that hasn't been submitted yet", async () => { // User attempts to vote on proposal that has not yet been submitted await expect( - linearERC20Voting.connect(tokenHolder2).vote(0, 1) - ).to.be.revertedWithCustomError(linearERC20Voting, "InvalidProposal"); + linearERC20Voting.connect(tokenHolder2).vote(0, 1), + ).to.be.revertedWithCustomError(linearERC20Voting, 'InvalidProposal'); }); - it("Votes cannot be cast after the voting period has ended", async () => { + it('Votes cannot be cast after the voting period has ended', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -499,12 +432,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -514,16 +442,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Users vote in support of proposal await expect( - linearERC20Voting.connect(tokenHolder2).vote(0, 1) - ).to.be.revertedWithCustomError(linearERC20Voting, "VotingEnded"); + linearERC20Voting.connect(tokenHolder2).vote(0, 1), + ).to.be.revertedWithCustomError(linearERC20Voting, 'VotingEnded'); }); - it("A voter cannot vote more than once on a proposal", async () => { + it('A voter cannot vote more than once on a proposal', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -534,12 +462,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -547,16 +470,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Users vote in support of proposal await linearERC20Voting.connect(tokenHolder2).vote(0, 1); await expect( - linearERC20Voting.connect(tokenHolder2).vote(0, 1) - ).to.be.revertedWithCustomError(linearERC20Voting, "AlreadyVoted"); + linearERC20Voting.connect(tokenHolder2).vote(0, 1), + ).to.be.revertedWithCustomError(linearERC20Voting, 'AlreadyVoted'); }); - it("Correctly counts proposal Yes votes", async () => { + it('Correctly counts proposal Yes votes', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -567,14 +490,9 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -597,12 +515,12 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect((await linearERC20Voting.getProposalVotes(0)).yesVotes).to.eq(600); }); - it("Correctly counts proposal No votes", async () => { + it('Correctly counts proposal No votes', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -613,14 +531,9 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -643,12 +556,12 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect((await linearERC20Voting.getProposalVotes(0)).noVotes).to.eq(600); }); - it("Correctly counts proposal Abstain votes", async () => { + it('Correctly counts proposal Abstain votes', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -659,50 +572,37 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); - expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq( - 0 - ); + expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq(0); // Token holder 1 votes but does not have any voting weight await linearERC20Voting.connect(tokenHolder1).vote(0, 2); - expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq( - 0 - ); + expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq(0); // Token holder 2 votes with voting weight of 300 await linearERC20Voting.connect(tokenHolder2).vote(0, 2); - expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq( - 300 - ); + expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq(300); // Token holder 3 votes with voting weight of 300 await linearERC20Voting.connect(tokenHolder3).vote(0, 2); - expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq( - 600 - ); + expect((await linearERC20Voting.getProposalVotes(0)).abstainVotes).to.eq(600); }); - it("A proposal is passed with enough Yes votes and quorum", async () => { + it('A proposal is passed with enough Yes votes and quorum', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -713,12 +613,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -738,12 +633,12 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await expect(await azorius.proposalState(0)).to.eq(1); }); - it("A proposal is not passed if there are more No votes than Yes votes", async () => { + it('A proposal is not passed if there are more No votes than Yes votes', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -754,12 +649,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -779,22 +669,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect(await azorius.proposalState(0)).to.eq(5); await expect( - azorius.executeProposal( - 0, - [await votesERC20.getAddress()], - [0], - [tokenTransferData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [0], [tokenTransferData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); }); - it("A proposal is not passed if quorum is not reached", async () => { + it('A proposal is not passed if quorum is not reached', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -805,12 +689,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -826,25 +705,19 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await expect(await linearERC20Voting.isPassed(0)).to.be.false; await expect( - azorius.executeProposal( - 0, - [await votesERC20.getAddress()], - [0], - [tokenTransferData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [0], [tokenTransferData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); // Proposal in the failed state expect(await azorius.proposalState(0)).to.eq(5); }); - it("A proposal is not passed if voting period is not over", async () => { + it('A proposal is not passed if voting period is not over', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -855,12 +728,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -874,25 +742,19 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await expect(await linearERC20Voting.isPassed(0)).to.be.false; await expect( - azorius.executeProposal( - 0, - [await votesERC20.getAddress()], - [0], - [tokenTransferData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [0], [tokenTransferData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); }); - it("Submitting a proposal emits the event with the associated proposal metadata", async () => { + it('Submitting a proposal emits the event with the associated proposal metadata', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -901,44 +763,36 @@ describe("Safe with Azorius module and linearERC20Voting", () => { operation: 0, }; - const proposalMetadata = "This is my amazing proposal!"; + const proposalMetadata = 'This is my amazing proposal!'; const tx = await azorius .connect(tokenHolder2) .submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction], - proposalMetadata + proposalMetadata, ); const receipt = await hre.ethers.provider.getTransactionReceipt(tx.hash); const data = receipt!.logs[1].data; const topics = receipt!.logs[1].topics; - const event = azorius.interface.decodeEventLog( - "ProposalCreated", - data, - topics - ); + const event = azorius.interface.decodeEventLog('ProposalCreated', data, topics); // Check that the event emits the correct values expect(event.transactions[0].to).to.be.equal(proposalTransaction.to); - expect(event.transactions[0].value).to.be.equal( - proposalTransaction.value - ); + expect(event.transactions[0].value).to.be.equal(proposalTransaction.value); expect(event.transactions[0].data).to.be.equal(proposalTransaction.data); - expect(event.transactions[0].operation).to.be.equal( - proposalTransaction.operation - ); + expect(event.transactions[0].operation).to.be.equal(proposalTransaction.operation); expect(event.metadata).to.be.equal(proposalMetadata); }); - it("A proposal can be created and executed", async () => { + it('A proposal can be created and executed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -949,18 +803,13 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); const txHash = await azorius.getTxHash( await votesERC20.getAddress(), 0n, tokenTransferData, - 0 + 0, ); const proposalTxHashes = await azorius.getProposalTxHashes(0); @@ -983,24 +832,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect(await azorius.proposalState(0)).to.eq(0); // Users haven't voted yet - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - false - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - false - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(false); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(false); // Users vote in support of proposal await linearERC20Voting.connect(tokenHolder2).vote(0, 1); await linearERC20Voting.connect(tokenHolder3).vote(0, 1); // Users have voted - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - true - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - true - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(true); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(true); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1014,9 +855,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -1025,7 +864,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { [await votesERC20.getAddress()], [0], [tokenTransferData], - [0] + [0], ); expect(await azorius.getProposal(0)).to.deep.eq([ @@ -1036,31 +875,29 @@ describe("Safe with Azorius module and linearERC20Voting", () => { 1, ]); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 0 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(deployer.address)).to.eq(600); // Proposal is in the executed state expect(await azorius.proposalState(0)).to.eq(3); }); - it("Multiple transactions can be executed from a single proposal", async () => { + it('Multiple transactions can be executed from a single proposal', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 100] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 100, + ]); - const tokenTransferData2 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 200] - ); + const tokenTransferData2 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 200, + ]); - const tokenTransferData3 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 300] - ); + const tokenTransferData3 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 300, + ]); const proposalTransaction1 = { to: await votesERC20.getAddress(), @@ -1087,9 +924,9 @@ describe("Safe with Azorius module and linearERC20Voting", () => { .connect(tokenHolder2) .submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1, proposalTransaction2, proposalTransaction3], - "" + '', ); // Proposal is active @@ -1111,9 +948,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -1126,24 +961,22 @@ describe("Safe with Azorius module and linearERC20Voting", () => { ], [0, 0, 0], [tokenTransferData1, tokenTransferData2, tokenTransferData3], - [0, 0, 0] + [0, 0, 0], ); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 0 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(deployer.address)).to.eq(600); // Proposal is executed expect(await azorius.proposalState(0)).to.eq(3); }); - it("Executing a proposal reverts if the transaction cannot be executed", async () => { + it('Executing a proposal reverts if the transaction cannot be executed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 700] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 700, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1154,12 +987,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -1180,37 +1008,27 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction await expect( - azorius.executeProposal( - 0, - [await votesERC20.getAddress()], - [0], - [tokenTransferData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "TxFailed"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [0], [tokenTransferData], [0]), + ).to.be.revertedWithCustomError(azorius, 'TxFailed'); // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); }); - it("If a proposal is not executed during the execution period, it becomes expired", async () => { + it('If a proposal is not executed during the execution period, it becomes expired', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1221,12 +1039,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -1255,20 +1068,14 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Execute the transaction await expect( - azorius.executeProposal( - 0, - [await votesERC20.getAddress()], - [0], - [tokenTransferData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [0], [tokenTransferData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); }); - it("A proposal with no transactions that passes goes immediately to executed", async () => { + it('A proposal with no transactions that passes goes immediately to executed', async () => { await azorius .connect(tokenHolder2) - .submitProposal(await linearERC20Voting.getAddress(), "0x", [], ""); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -1288,143 +1095,116 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await expect(await azorius.proposalState(0)).to.eq(3); }); - it("Only the owner can update the timelock period on Azorius", async () => { + it('Only the owner can update the timelock period on Azorius', async () => { expect(await azorius.timelockPeriod()).to.eq(60); await azorius.connect(gnosisSafeOwner).updateTimelockPeriod(70); expect(await azorius.timelockPeriod()).to.eq(70); - await expect( - azorius.connect(tokenHolder1).updateTimelockPeriod(80) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(azorius.connect(tokenHolder1).updateTimelockPeriod(80)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the owner can update the execution period on Azorius", async () => { + it('Only the owner can update the execution period on Azorius', async () => { expect(await azorius.executionPeriod()).to.eq(60); await azorius.connect(gnosisSafeOwner).updateExecutionPeriod(100); expect(await azorius.executionPeriod()).to.eq(100); - await expect( - azorius.connect(tokenHolder1).updateExecutionPeriod(110) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(azorius.connect(tokenHolder1).updateExecutionPeriod(110)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the owner can update the quorum numerator on the ERC20LinearVoting", async () => { + it('Only the owner can update the quorum numerator on the ERC20LinearVoting', async () => { expect(await linearERC20Voting.quorumNumerator()).to.eq(500000); - await linearERC20Voting - .connect(gnosisSafeOwner) - .updateQuorumNumerator(600000); + await linearERC20Voting.connect(gnosisSafeOwner).updateQuorumNumerator(600000); expect(await linearERC20Voting.quorumNumerator()).to.eq(600000); await expect( - linearERC20Voting.connect(tokenHolder1).updateQuorumNumerator(700000) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC20Voting.connect(tokenHolder1).updateQuorumNumerator(700000), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Quorum numerator cannot be updated to a value larger than the denominator", async () => { + it('Quorum numerator cannot be updated to a value larger than the denominator', async () => { await expect( - linearERC20Voting - .connect(gnosisSafeOwner) - .updateQuorumNumerator(1000001) - ).to.be.revertedWithCustomError( - linearERC20Voting, - "InvalidQuorumNumerator" - ); + linearERC20Voting.connect(gnosisSafeOwner).updateQuorumNumerator(1000001), + ).to.be.revertedWithCustomError(linearERC20Voting, 'InvalidQuorumNumerator'); }); - it("Only the owner can update the basis numerator on the ERC20LinearVoting", async () => { + it('Only the owner can update the basis numerator on the ERC20LinearVoting', async () => { expect(await linearERC20Voting.basisNumerator()).to.eq(500000); - await linearERC20Voting - .connect(gnosisSafeOwner) - .updateBasisNumerator(600000); + await linearERC20Voting.connect(gnosisSafeOwner).updateBasisNumerator(600000); expect(await linearERC20Voting.basisNumerator()).to.eq(600000); await expect( - linearERC20Voting.connect(tokenHolder1).updateBasisNumerator(700000) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC20Voting.connect(tokenHolder1).updateBasisNumerator(700000), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Basis numerator cannot be updated to a value larger than the denominator", async () => { + it('Basis numerator cannot be updated to a value larger than the denominator', async () => { await expect( - linearERC20Voting.connect(gnosisSafeOwner).updateBasisNumerator(1000001) - ).to.be.revertedWithCustomError( - linearERC20Voting, - "InvalidBasisNumerator" - ); + linearERC20Voting.connect(gnosisSafeOwner).updateBasisNumerator(1000001), + ).to.be.revertedWithCustomError(linearERC20Voting, 'InvalidBasisNumerator'); }); - it("Only the owner can update the proposer weight on the ERC20LinearVoting", async () => { + it('Only the owner can update the proposer weight on the ERC20LinearVoting', async () => { expect(await linearERC20Voting.requiredProposerWeight()).to.eq(300); - await linearERC20Voting - .connect(gnosisSafeOwner) - .updateRequiredProposerWeight(1); + await linearERC20Voting.connect(gnosisSafeOwner).updateRequiredProposerWeight(1); expect(await linearERC20Voting.requiredProposerWeight()).to.eq(1); await expect( - linearERC20Voting.connect(tokenHolder1).updateRequiredProposerWeight(2) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC20Voting.connect(tokenHolder1).updateRequiredProposerWeight(2), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Linear ERC20 voting contract cannot be setup with an invalid governance token address", async () => { + it('Linear ERC20 voting contract cannot be setup with an invalid governance token address', async () => { const abiCoder = new ethers.AbiCoder(); // Deploy Linear ERC20 Voting Strategy - linearERC20Voting = await new LinearERC20Voting__factory( - deployer - ).deploy(); + linearERC20Voting = await new LinearERC20Voting__factory(deployer).deploy(); const linearERC20VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC20Voting__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - [ - "address", - "address", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], - [ - gnosisSafeOwner.address, // owner - ethers.ZeroAddress, // governance token - await azorius.getAddress(), // Azorius module - 60, // voting period in blocks - 0, // proposer weight - 500000, // quorom numerator, denominator is 1,000,000, so quorum percentage is 50% - 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] - ), - ] - ); + LinearERC20Voting__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['address', 'address', 'address', 'uint32', 'uint256', 'uint256', 'uint256'], + [ + gnosisSafeOwner.address, // owner + ethers.ZeroAddress, // governance token + await azorius.getAddress(), // Azorius module + 60, // voting period in blocks + 0, // proposer weight + 500000, // quorom numerator, denominator is 1,000,000, so quorum percentage is 50% + 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) + ], + ), + ]); await expect( moduleProxyFactory.deployModule( await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" - ) + '10031021', + ), ).to.be.reverted; }); - it("An invalid vote type cannot be cast", async () => { + it('An invalid vote type cannot be cast', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1435,29 +1215,24 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // Users cast invalid vote types await expect( - linearERC20Voting.connect(tokenHolder2).vote(0, 3) - ).to.be.revertedWithCustomError(linearERC20Voting, "InvalidVote"); + linearERC20Voting.connect(tokenHolder2).vote(0, 3), + ).to.be.revertedWithCustomError(linearERC20Voting, 'InvalidVote'); await expect( - linearERC20Voting.connect(tokenHolder2).vote(0, 4) - ).to.be.revertedWithCustomError(linearERC20Voting, "InvalidVote"); + linearERC20Voting.connect(tokenHolder2).vote(0, 4), + ).to.be.revertedWithCustomError(linearERC20Voting, 'InvalidVote'); await expect( - linearERC20Voting.connect(tokenHolder2).vote(0, 5) - ).to.be.revertedWithCustomError(linearERC20Voting, "InvalidVote"); + linearERC20Voting.connect(tokenHolder2).vote(0, 5), + ).to.be.revertedWithCustomError(linearERC20Voting, 'InvalidVote'); }); - it("Azorius can be setup with multiple strategies", async () => { + it('Azorius can be setup with multiple strategies', async () => { const abiCoder = new ethers.AbiCoder(); // Deploy Azorius module @@ -1465,110 +1240,86 @@ describe("Safe with Azorius module and linearERC20Voting", () => { const azoriusSetupCalldata = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ + Azorius__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - [ - "address", - "address", - "address", - "address[]", - "uint256", - "uint256", - ], + ['address', 'address', 'address', 'address[]', 'uint256', 'uint256'], [ gnosisSafeOwner.address, await gnosisSafe.getAddress(), await gnosisSafe.getAddress(), - [ - tokenHolder1.address, - tokenHolder2.address, - tokenHolder3.address, - ], + [tokenHolder1.address, tokenHolder2.address, tokenHolder3.address], 60, // timelock period in blocks 60, // execution period in blocks - ] + ], ), ]); await moduleProxyFactory.deployModule( await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); const predictedAzoriusAddress = await calculateProxyAddress( moduleProxyFactory, await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); - azorius = await hre.ethers.getContractAt( - "Azorius", - predictedAzoriusAddress - ); + azorius = await hre.ethers.getContractAt('Azorius', predictedAzoriusAddress); expect(await azorius.isStrategyEnabled(tokenHolder1.address)).to.eq(true); expect(await azorius.isStrategyEnabled(tokenHolder2.address)).to.eq(true); expect(await azorius.isStrategyEnabled(tokenHolder3.address)).to.eq(true); }); - it("Only a valid proposer can submit proposals", async () => { + it('Only a valid proposer can submit proposals', async () => { const abiCoder = new ethers.AbiCoder(); // Deploy Mock Voting Strategy - const mockVotingStrategyMastercopy = - await new MockVotingStrategy__factory(deployer).deploy(); + const mockVotingStrategyMastercopy = await new MockVotingStrategy__factory(deployer).deploy(); const mockVotingStrategySetupCalldata = // eslint-disable-next-line camelcase - MockVotingStrategy__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["address"], - [ - tokenHolder1.address, // tokenHolder1 is the only valid proposer - ] - ), - ] - ); + MockVotingStrategy__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['address'], + [ + tokenHolder1.address, // tokenHolder1 is the only valid proposer + ], + ), + ]); await moduleProxyFactory.deployModule( await mockVotingStrategyMastercopy.getAddress(), mockVotingStrategySetupCalldata, - "10031021" + '10031021', ); const predictedMockVotingStrategyAddress = await calculateProxyAddress( moduleProxyFactory, await mockVotingStrategyMastercopy.getAddress(), mockVotingStrategySetupCalldata, - "10031021" + '10031021', ); mockVotingStrategy = await hre.ethers.getContractAt( - "MockVotingStrategy", - predictedMockVotingStrategyAddress + 'MockVotingStrategy', + predictedMockVotingStrategyAddress, ); // Enable the Mock Voting strategy on Azorius - await azorius - .connect(gnosisSafeOwner) - .enableStrategy(await mockVotingStrategy.getAddress()); + await azorius.connect(gnosisSafeOwner).enableStrategy(await mockVotingStrategy.getAddress()); - expect(await mockVotingStrategy.isProposer(tokenHolder1.address)).to.eq( - true - ); - expect(await mockVotingStrategy.isProposer(tokenHolder2.address)).to.eq( - false - ); + expect(await mockVotingStrategy.isProposer(tokenHolder1.address)).to.eq(true); + expect(await mockVotingStrategy.isProposer(tokenHolder2.address)).to.eq(false); // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1580,35 +1331,25 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // This user was setup as the proposer on the MockVotingStrategy, so should be able to submit a proposal await azorius .connect(tokenHolder1) - .submitProposal( - await mockVotingStrategy.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await mockVotingStrategy.getAddress(), '0x', [proposalTransaction], ''); // This user was not setup as the proposer, and so should not be able to submit a proposal await expect( azorius .connect(tokenHolder2) - .submitProposal( - await mockVotingStrategy.getAddress(), - "0x", - [proposalTransaction], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer"); + .submitProposal(await mockVotingStrategy.getAddress(), '0x', [proposalTransaction], ''), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer'); expect(await mockVotingStrategy.isPassed(0)).to.eq(false); expect(await mockVotingStrategy.votingEndBlock(0)).to.eq(0); }); - it("A proposal cannot be executed if targets array length is zero", async () => { + it('A proposal cannot be executed if targets array length is zero', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1619,18 +1360,13 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); const txHash = await azorius.getTxHash( await votesERC20.getAddress(), 0n, tokenTransferData, - 0 + 0, ); const proposalTxHashes = await azorius.getProposalTxHashes(0); @@ -1653,24 +1389,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect(await azorius.proposalState(0)).to.eq(0); // Users haven't voted yet - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - false - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - false - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(false); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(false); // Users vote in support of proposal await linearERC20Voting.connect(tokenHolder2).vote(0, 1); await linearERC20Voting.connect(tokenHolder3).vote(0, 1); // Users have voted - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - true - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - true - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(true); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(true); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1684,23 +1412,22 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction - await expect( - azorius.executeProposal(0, [], [], [], []) - ).to.be.revertedWithCustomError(azorius, "InvalidTxs"); + await expect(azorius.executeProposal(0, [], [], [], [])).to.be.revertedWithCustomError( + azorius, + 'InvalidTxs', + ); }); - it("A proposal cannot be executed if unequal array lengths are passed", async () => { + it('A proposal cannot be executed if unequal array lengths are passed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1711,18 +1438,13 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); const txHash = await azorius.getTxHash( await votesERC20.getAddress(), 0n, tokenTransferData, - 0 + 0, ); const proposalTxHashes = await azorius.getProposalTxHashes(0); @@ -1745,24 +1467,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect(await azorius.proposalState(0)).to.eq(0); // Users haven't voted yet - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - false - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - false - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(false); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(false); // Users vote in support of proposal await linearERC20Voting.connect(tokenHolder2).vote(0, 1); await linearERC20Voting.connect(tokenHolder3).vote(0, 1); // Users have voted - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - true - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - true - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(true); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(true); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1776,23 +1490,21 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction await expect( - azorius.executeProposal(0, [await votesERC20.getAddress()], [], [], [0]) - ).to.be.revertedWithCustomError(azorius, "InvalidArrayLengths"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [], [], [0]), + ).to.be.revertedWithCustomError(azorius, 'InvalidArrayLengths'); }); - it("A proposal cannot be executed if too many TXs are passed to it", async () => { + it('A proposal cannot be executed if too many TXs are passed to it', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1803,18 +1515,13 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); const txHash = await azorius.getTxHash( await votesERC20.getAddress(), 0n, tokenTransferData, - 0 + 0, ); const proposalTxHashes = await azorius.getProposalTxHashes(0); @@ -1837,24 +1544,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { expect(await azorius.proposalState(0)).to.eq(0); // Users haven't voted yet - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - false - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - false - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(false); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(false); // Users vote in support of proposal await linearERC20Voting.connect(tokenHolder2).vote(0, 1); await linearERC20Voting.connect(tokenHolder3).vote(0, 1); // Users have voted - expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq( - true - ); - expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq( - true - ); + expect(await linearERC20Voting.hasVoted(0, tokenHolder2.address)).to.eq(true); + expect(await linearERC20Voting.hasVoted(0, tokenHolder3.address)).to.eq(true); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1868,9 +1567,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 600 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(600); expect(await votesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -1880,22 +1577,22 @@ describe("Safe with Azorius module and linearERC20Voting", () => { [await votesERC20.getAddress(), await votesERC20.getAddress()], [0, 0], [tokenTransferData, tokenTransferData], - [0, 0] - ) - ).to.be.revertedWithCustomError(azorius, "InvalidTxs"); + [0, 0], + ), + ).to.be.revertedWithCustomError(azorius, 'InvalidTxs'); }); - it("A proposal cannot be executed with the wrong TXs passed to it", async () => { + it('A proposal cannot be executed with the wrong TXs passed to it', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); - const tokenTransferData2 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 700] - ); + const tokenTransferData2 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 700, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1906,12 +1603,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); // Users vote in support of proposal await linearERC20Voting.connect(tokenHolder2).vote(0, 1); @@ -1928,22 +1620,16 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Execute the transaction await expect( - azorius.executeProposal( - 0, - [await votesERC20.getAddress()], - [0], - [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "InvalidTxHash"); + azorius.executeProposal(0, [await votesERC20.getAddress()], [0], [tokenTransferData2], [0]), + ).to.be.revertedWithCustomError(azorius, 'InvalidTxHash'); }); it("A non-proposer can't submit a proposal", async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -1952,60 +1638,39 @@ describe("Safe with Azorius module and linearERC20Voting", () => { operation: 0, }; - expect(await linearERC20Voting.isProposer(tokenHolder2.address)).to.eq( - true - ); + expect(await linearERC20Voting.isProposer(tokenHolder2.address)).to.eq(true); expect(await linearERC20Voting.isProposer(deployer.address)).to.eq(false); await expect( azorius .connect(deployer) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer()"); - - await linearERC20Voting - .connect(gnosisSafeOwner) - .updateRequiredProposerWeight(301); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer()'); - expect(await linearERC20Voting.isProposer(tokenHolder2.address)).to.eq( - false - ); + await linearERC20Voting.connect(gnosisSafeOwner).updateRequiredProposerWeight(301); + + expect(await linearERC20Voting.isProposer(tokenHolder2.address)).to.eq(false); expect(await linearERC20Voting.isProposer(deployer.address)).to.eq(false); await expect( azorius .connect(deployer) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer"); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer'); await expect( azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer"); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer'); }); - it("isPassed logic is correct", async () => { + it('isPassed logic is correct', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 600] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 600, + ]); const proposalTransaction = { to: await votesERC20.getAddress(), @@ -2017,12 +1682,7 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Submit first proposal await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); await linearERC20Voting.connect(tokenHolder2).vote(0, 1); await linearERC20Voting.connect(tokenHolder3).vote(0, 2); @@ -2036,19 +1696,12 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Quorum and basis should be met expect(await linearERC20Voting.isPassed(0)).to.eq(true); - await linearERC20Voting - .connect(gnosisSafeOwner) - .updateQuorumNumerator(600000); + await linearERC20Voting.connect(gnosisSafeOwner).updateQuorumNumerator(600000); // Submit second proposal await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); await linearERC20Voting.connect(tokenHolder2).vote(1, 1); await linearERC20Voting.connect(tokenHolder3).vote(1, 2); @@ -2063,19 +1716,12 @@ describe("Safe with Azorius module and linearERC20Voting", () => { // Only 50% of tokens have voted quorum should not be reached expect(await linearERC20Voting.isPassed(1)).to.eq(false); - await linearERC20Voting - .connect(gnosisSafeOwner) - .updateQuorumNumerator(250000); + await linearERC20Voting.connect(gnosisSafeOwner).updateQuorumNumerator(250000); // Submit third proposal await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC20Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC20Voting.getAddress(), '0x', [proposalTransaction], ''); await linearERC20Voting.connect(tokenHolder2).vote(2, 0); await linearERC20Voting.connect(tokenHolder3).vote(2, 1); diff --git a/test/Azorius-LinearERC721Voting.test.ts b/test/Azorius-LinearERC721Voting.test.ts index a55c6f9f..42d67ee8 100644 --- a/test/Azorius-LinearERC721Voting.test.ts +++ b/test/Azorius-LinearERC721Voting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { GnosisSafe, GnosisSafeProxyFactory, @@ -15,7 +13,13 @@ import { MockERC721__factory, MockContract__factory, GnosisSafeL2__factory, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, + getMockContract, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, @@ -24,15 +28,10 @@ import { calculateProxyAddress, mockTransaction, mockRevertTransaction, -} from "./helpers"; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, - getMockContract, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; +import time from './time'; -describe("Safe with Azorius module and linearERC721Voting", () => { +describe('Safe with Azorius module and linearERC721Voting', () => { const abiCoder = new ethers.AbiCoder(); // Deployed contracts @@ -70,14 +69,9 @@ describe("Safe with Azorius module and linearERC721Voting", () => { // Gnosis let createGnosisSetupCalldata: string; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); - async function mintNFT( - contract: MockERC721, - receiver: SignerWithAddress - ): Promise { + async function mintNFT(contract: MockERC721, receiver: SignerWithAddress): Promise { await contract.connect(receiver).mint(receiver.address); } @@ -86,27 +80,25 @@ describe("Safe with Azorius module and linearERC721Voting", () => { moduleProxyFactory = getModuleProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const abiCoder = new ethers.AbiCoder(); - // Get the signer accounts [deployer, gnosisSafeOwner, tokenHolder1, tokenHolder2, tokenHolder3] = await hre.ethers.getSigners(); // Get Gnosis Safe Proxy factory gnosisSafeProxyFactory = await hre.ethers.getContractAt( - "GnosisSafeProxyFactory", - await gnosisSafeProxyFactory.getAddress() + 'GnosisSafeProxyFactory', + await gnosisSafeProxyFactory.getAddress(), ); // Get module proxy factory moduleProxyFactory = await hre.ethers.getContractAt( - "ModuleProxyFactory", - await moduleProxyFactory.getAddress() + 'ModuleProxyFactory', + await moduleProxyFactory.getAddress(), ); createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ [gnosisSafeOwner.address], 1, ethers.ZeroAddress, @@ -121,20 +113,17 @@ describe("Safe with Azorius module and linearERC721Voting", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, - saltNum + saltNum, ); - gnosisSafe = await hre.ethers.getContractAt( - "GnosisSafe", - predictedGnosisSafeAddress - ); + gnosisSafe = await hre.ethers.getContractAt('GnosisSafe', predictedGnosisSafeAddress); // Deploy Mock NFTs mockNFT1 = await new MockERC721__factory(deployer).deploy(); @@ -159,9 +148,7 @@ describe("Safe with Azorius module and linearERC721Voting", () => { holder2Ids = [0]; holder3Ids = [1, 1]; - mintNFTData = mockNFT1.interface.encodeFunctionData("mint", [ - deployer.address, - ]); + mintNFTData = mockNFT1.interface.encodeFunctionData('mint', [deployer.address]); proposalTransaction = { to: await mockNFT1.getAddress(), @@ -175,9 +162,9 @@ describe("Safe with Azorius module and linearERC721Voting", () => { const azoriusSetupCalldata = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ + Azorius__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ gnosisSafeOwner.address, await gnosisSafe.getAddress(), @@ -185,91 +172,80 @@ describe("Safe with Azorius module and linearERC721Voting", () => { [], 60, // timelock period in blocks 60, // execution period in blocks - ] + ], ), ]); await moduleProxyFactory.deployModule( await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); const predictedAzoriusAddress = await calculateProxyAddress( moduleProxyFactory, await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); - azorius = await hre.ethers.getContractAt( - "Azorius", - predictedAzoriusAddress - ); + azorius = await hre.ethers.getContractAt('Azorius', predictedAzoriusAddress); // Deploy Linear ERC721 Voting Mastercopy - linearERC721VotingMastercopy = await new LinearERC721Voting__factory( - deployer - ).deploy(); + linearERC721VotingMastercopy = await new LinearERC721Voting__factory(deployer).deploy(); const linearERC721VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC721Voting__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - [ - "address", - "address[]", - "uint256[]", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], - [ - gnosisSafeOwner.address, // owner - [await mockNFT1.getAddress(), await mockNFT2.getAddress()], // NFT addresses - [1, 2], // NFT weights - await azorius.getAddress(), // Azorius module - 60, // voting period in blocks - 2, // quorom threshold - 2, // proposer threshold - 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] - ), - ] - ); + LinearERC721Voting__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + [ + 'address', + 'address[]', + 'uint256[]', + 'address', + 'uint32', + 'uint256', + 'uint256', + 'uint256', + ], + [ + gnosisSafeOwner.address, // owner + [await mockNFT1.getAddress(), await mockNFT2.getAddress()], // NFT addresses + [1, 2], // NFT weights + await azorius.getAddress(), // Azorius module + 60, // voting period in blocks + 2, // quorom threshold + 2, // proposer threshold + 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) + ], + ), + ]); await moduleProxyFactory.deployModule( await linearERC721VotingMastercopy.getAddress(), linearERC721VotingSetupCalldata, - "10031021" + '10031021', ); const predictedlinearERC721VotingAddress = await calculateProxyAddress( moduleProxyFactory, await linearERC721VotingMastercopy.getAddress(), linearERC721VotingSetupCalldata, - "10031021" + '10031021', ); linearERC721Voting = await hre.ethers.getContractAt( - "LinearERC721Voting", - predictedlinearERC721VotingAddress + 'LinearERC721Voting', + predictedlinearERC721VotingAddress, ); // Enable the Linear Voting strategy on Azorius - await azorius - .connect(gnosisSafeOwner) - .enableStrategy(await linearERC721Voting.getAddress()); + await azorius.connect(gnosisSafeOwner).enableStrategy(await linearERC721Voting.getAddress()); // Create transaction on Gnosis Safe to setup Azorius module - const enableAzoriusModuleData = gnosisSafe.interface.encodeFunctionData( - "enableModule", - [await azorius.getAddress()] - ); + const enableAzoriusModuleData = gnosisSafe.interface.encodeFunctionData('enableModule', [ + await azorius.getAddress(), + ]); const enableAzoriusModuleTx = buildSafeTransaction({ to: await gnosisSafe.getAddress(), @@ -278,13 +254,7 @@ describe("Safe with Azorius module and linearERC721Voting", () => { nonce: await gnosisSafe.nonce(), }); - const sigs = [ - await safeSignTypedData( - gnosisSafeOwner, - gnosisSafe, - enableAzoriusModuleTx - ), - ]; + const sigs = [await safeSignTypedData(gnosisSafeOwner, gnosisSafe, enableAzoriusModuleTx)]; const signatureBytes = buildSignatureBytes(sigs); @@ -300,127 +270,106 @@ describe("Safe with Azorius module and linearERC721Voting", () => { enableAzoriusModuleTx.gasPrice, enableAzoriusModuleTx.gasToken, enableAzoriusModuleTx.refundReceiver, - signatureBytes - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - describe("Safe with Azorius module and linearERC721Voting", () => { - it("Gets correctly initialized", async () => { + describe('Safe with Azorius module and linearERC721Voting', () => { + it('Gets correctly initialized', async () => { expect(await linearERC721Voting.owner()).to.eq(gnosisSafeOwner.address); - expect(await linearERC721Voting.tokenAddresses(0)).to.eq( - await mockNFT1.getAddress() - ); - expect(await linearERC721Voting.tokenAddresses(1)).to.eq( - await mockNFT2.getAddress() - ); - expect(await linearERC721Voting.azoriusModule()).to.eq( - await azorius.getAddress() - ); + expect(await linearERC721Voting.tokenAddresses(0)).to.eq(await mockNFT1.getAddress()); + expect(await linearERC721Voting.tokenAddresses(1)).to.eq(await mockNFT2.getAddress()); + expect(await linearERC721Voting.azoriusModule()).to.eq(await azorius.getAddress()); expect(await linearERC721Voting.votingPeriod()).to.eq(60); expect(await linearERC721Voting.quorumThreshold()).to.eq(2); expect(await linearERC721Voting.proposerThreshold()).to.eq(2); }); - it("A strategy cannot be enabled more than once", async () => { + it('A strategy cannot be enabled more than once', async () => { await expect( - azorius - .connect(gnosisSafeOwner) - .enableStrategy(await linearERC721Voting.getAddress()) - ).to.be.revertedWithCustomError(azorius, "StrategyEnabled()"); + azorius.connect(gnosisSafeOwner).enableStrategy(await linearERC721Voting.getAddress()), + ).to.be.revertedWithCustomError(azorius, 'StrategyEnabled()'); }); - it("The owner can change the Azorius Module on the Strategy", async () => { - await linearERC721Voting - .connect(gnosisSafeOwner) - .setAzorius(deployer.address); + it('The owner can change the Azorius Module on the Strategy', async () => { + await linearERC721Voting.connect(gnosisSafeOwner).setAzorius(deployer.address); expect(await linearERC721Voting.azoriusModule()).to.eq(deployer.address); }); - it("A non-owner cannot change the Azorius Module on the Strategy", async () => { + it('A non-owner cannot change the Azorius Module on the Strategy', async () => { await expect( - linearERC721Voting.connect(tokenHolder1).setAzorius(deployer.address) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC721Voting.connect(tokenHolder1).setAzorius(deployer.address), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("The owner can update the voting period", async () => { + it('The owner can update the voting period', async () => { expect(await linearERC721Voting.votingPeriod()).to.eq(60); await linearERC721Voting.connect(gnosisSafeOwner).updateVotingPeriod(120); expect(await linearERC721Voting.votingPeriod()).to.eq(120); }); - it("A non-owner cannot update the strategy voting period", async () => { + it('A non-owner cannot update the strategy voting period', async () => { await expect( - linearERC721Voting.connect(tokenHolder1).updateVotingPeriod(120) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC721Voting.connect(tokenHolder1).updateVotingPeriod(120), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("The owner can update the timelock period", async () => { + it('The owner can update the timelock period', async () => { expect(await azorius.timelockPeriod()).to.eq(60); await azorius.connect(gnosisSafeOwner).updateTimelockPeriod(120); expect(await azorius.timelockPeriod()).to.eq(120); }); - it("A non-owner cannot update the strategy timelock period", async () => { - await expect( - azorius.connect(tokenHolder1).updateTimelockPeriod(120) - ).to.be.revertedWith("Ownable: caller is not the owner"); + it('A non-owner cannot update the strategy timelock period', async () => { + await expect(azorius.connect(tokenHolder1).updateTimelockPeriod(120)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Getting proposal state on an invalid proposal ID reverts", async () => { + it('Getting proposal state on an invalid proposal ID reverts', async () => { await expect(azorius.proposalState(0)).to.be.revertedWithCustomError( azorius, - "InvalidProposal" + 'InvalidProposal', ); await expect(azorius.proposalState(0)).to.be.revertedWithCustomError( azorius, - "InvalidProposal" + 'InvalidProposal', ); }); - it("A proposal cannot be submitted if the specified strategy has not been enabled", async () => { + it('A proposal cannot be submitted if the specified strategy has not been enabled', async () => { // Use an incorrect address for the strategy await expect( azorius .connect(tokenHolder2) - .submitProposal( - await mockNFT1.getAddress(), - "0x", - [await mockTransaction()], - "" - ) - ).to.be.revertedWithCustomError(azorius, "StrategyDisabled"); + .submitProposal(await mockNFT1.getAddress(), '0x', [await mockTransaction()], ''), + ).to.be.revertedWithCustomError(azorius, 'StrategyDisabled'); }); - it("Proposal cannot be received by the strategy from address other than Azorius", async () => { + it('Proposal cannot be received by the strategy from address other than Azorius', async () => { // Submit call from address that isn't Azorius module - await expect( - linearERC721Voting.initializeProposal("0x") - ).to.be.revertedWithCustomError(linearERC721Voting, "OnlyAzorius"); + await expect(linearERC721Voting.initializeProposal('0x')).to.be.revertedWithCustomError( + linearERC721Voting, + 'OnlyAzorius', + ); }); it("Votes cannot be cast on a proposal that hasn't been submitted yet", async () => { // User attempts to vote on proposal that has not yet been submitted await expect( - linearERC721Voting - .connect(tokenHolder1) - .vote(0, 1, holder1Tokens, holder1Ids) - ).to.be.revertedWithCustomError(linearERC721Voting, "InvalidProposal"); + linearERC721Voting.connect(tokenHolder1).vote(0, 1, holder1Tokens, holder1Ids), + ).to.be.revertedWithCustomError(linearERC721Voting, 'InvalidProposal'); }); - it("Votes cannot be cast after the voting period has ended", async () => { + it('Votes cannot be cast after the voting period has ended', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -430,75 +379,50 @@ describe("Safe with Azorius module and linearERC721Voting", () => { // Users vote in support of proposal await expect( - linearERC721Voting - .connect(tokenHolder1) - .vote(0, 1, holder1Tokens, holder1Ids) - ).to.be.revertedWithCustomError(linearERC721Voting, "VotingEnded"); + linearERC721Voting.connect(tokenHolder1).vote(0, 1, holder1Tokens, holder1Ids), + ).to.be.revertedWithCustomError(linearERC721Voting, 'VotingEnded'); }); - it("A voter cannot vote more than once on a proposal with the same id", async () => { + it('A voter cannot vote more than once on a proposal with the same id', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // User votes in support of proposal - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); // User votes again await expect( - linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids) - ).to.be.revertedWithCustomError(linearERC721Voting, "IdAlreadyVoted"); + linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids), + ).to.be.revertedWithCustomError(linearERC721Voting, 'IdAlreadyVoted'); }); - it("A voter can vote more than once with different ids", async () => { + it('A voter can vote more than once with different ids', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // User votes in support of proposal - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, [await mockNFT1.getAddress()], [1]); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, [await mockNFT1.getAddress()], [1]); // User votes again - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, [await mockNFT2.getAddress()], [1]); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, [await mockNFT2.getAddress()], [1]); expect((await linearERC721Voting.getProposalVotes(0)).yesVotes).to.eq(3); }); - it("Correctly counts proposal Yes votes", async () => { + it('Correctly counts proposal Yes votes', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -506,38 +430,27 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect((await linearERC721Voting.getProposalVotes(0)).yesVotes).to.eq(0); // Token holder 1 votes with voting weight of 1 - await linearERC721Voting - .connect(tokenHolder1) - .vote(0, 1, holder1Tokens, holder1Ids); + await linearERC721Voting.connect(tokenHolder1).vote(0, 1, holder1Tokens, holder1Ids); expect((await linearERC721Voting.getProposalVotes(0)).yesVotes).to.eq(1); // Token holder 2 votes with voting weight of 2 - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); expect((await linearERC721Voting.getProposalVotes(0)).yesVotes).to.eq(3); // Token holder 3 votes with voting weight of 3 - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); expect((await linearERC721Voting.getProposalVotes(0)).yesVotes).to.eq(6); }); - it("Correctly counts proposal No votes", async () => { + it('Correctly counts proposal No votes', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -545,83 +458,53 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect((await linearERC721Voting.getProposalVotes(0)).noVotes).to.eq(0); // Token holder 1 votes with voting weight of 1 - await linearERC721Voting - .connect(tokenHolder1) - .vote(0, 0, holder1Tokens, holder1Ids); + await linearERC721Voting.connect(tokenHolder1).vote(0, 0, holder1Tokens, holder1Ids); expect((await linearERC721Voting.getProposalVotes(0)).noVotes).to.eq(1); // Token holder 2 votes with voting weight of 2 - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 0, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 0, holder2Tokens, holder2Ids); expect((await linearERC721Voting.getProposalVotes(0)).noVotes).to.eq(3); // Token holder 3 votes with voting weight of 3 - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 0, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 0, holder3Tokens, holder3Ids); expect((await linearERC721Voting.getProposalVotes(0)).noVotes).to.eq(6); }); - it("Correctly counts proposal Abstain votes", async () => { + it('Correctly counts proposal Abstain votes', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); - expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq( - 0 - ); + expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq(0); // Token holder 1 votes with voting weight of 1 - await linearERC721Voting - .connect(tokenHolder1) - .vote(0, 2, holder1Tokens, holder1Ids); + await linearERC721Voting.connect(tokenHolder1).vote(0, 2, holder1Tokens, holder1Ids); - expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq( - 1 - ); + expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq(1); // Token holder 2 votes with voting weight of 2 - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 2, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 2, holder2Tokens, holder2Ids); - expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq( - 3 - ); + expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq(3); // Token holder 3 votes with voting weight of 3 - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 2, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 2, holder3Tokens, holder3Ids); - expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq( - 6 - ); + expect((await linearERC721Voting.getProposalVotes(0)).abstainVotes).to.eq(6); }); - it("A proposal is passed with enough Yes votes and quorum", async () => { + it('A proposal is passed with enough Yes votes and quorum', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -629,12 +512,8 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await linearERC721Voting.isPassed(0)).to.be.false; // Users vote in support of proposal - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -645,15 +524,10 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await azorius.proposalState(0)).to.eq(1); }); - it("A proposal is not passed if there are more No votes than Yes votes", async () => { + it('A proposal is not passed if there are more No votes than Yes votes', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -661,12 +535,8 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await linearERC721Voting.isPassed(0)).to.be.false; // Users vote against - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 0, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 0, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 0, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 0, holder3Tokens, holder3Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -677,25 +547,14 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect(await azorius.proposalState(0)).to.eq(5); await expect( - azorius.executeProposal( - 0, - [await mockNFT1.getAddress()], - [0], - [mintNFTData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await mockNFT1.getAddress()], [0], [mintNFTData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); }); - it("A proposal is not passed if quorum is not reached", async () => { + it('A proposal is not passed if quorum is not reached', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -703,9 +562,7 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await linearERC721Voting.isPassed(0)).to.be.false; // User votes "Yes" - await linearERC721Voting - .connect(tokenHolder1) - .vote(0, 1, holder1Tokens, holder1Ids); + await linearERC721Voting.connect(tokenHolder1).vote(0, 1, holder1Tokens, holder1Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -713,28 +570,17 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await linearERC721Voting.isPassed(0)).to.be.false; await expect( - azorius.executeProposal( - 0, - [await mockNFT1.getAddress()], - [0], - [mintNFTData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await mockNFT1.getAddress()], [0], [mintNFTData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); // Proposal in the failed state expect(await azorius.proposalState(0)).to.eq(5); }); - it("A proposal is not passed if voting period is not over", async () => { + it('A proposal is not passed if voting period is not over', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -742,78 +588,50 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await linearERC721Voting.isPassed(0)).to.be.false; // Users vote "Yes" - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); await expect(await linearERC721Voting.isPassed(0)).to.be.false; await expect( - azorius.executeProposal( - 0, - [await mockNFT1.getAddress()], - [0], - [mintNFTData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await mockNFT1.getAddress()], [0], [mintNFTData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); }); - it("Submitting a proposal emits the event with the associated proposal metadata", async () => { - const proposalMetadata = "This is my amazing proposal!"; + it('Submitting a proposal emits the event with the associated proposal metadata', async () => { + const proposalMetadata = 'This is my amazing proposal!'; const tx = await azorius .connect(tokenHolder2) .submitProposal( await linearERC721Voting.getAddress(), - "0x", + '0x', [proposalTransaction], - proposalMetadata + proposalMetadata, ); const receipt = await hre.ethers.provider.getTransactionReceipt(tx.hash); const data = receipt!.logs[1].data; const topics = receipt!.logs[1].topics; - const event = azorius.interface.decodeEventLog( - "ProposalCreated", - data, - topics - ); + const event = azorius.interface.decodeEventLog('ProposalCreated', data, topics); // Check that the event emits the correct values expect(event.transactions[0].to).to.be.equal(proposalTransaction.to); - expect(event.transactions[0].value).to.be.equal( - proposalTransaction.value - ); + expect(event.transactions[0].value).to.be.equal(proposalTransaction.value); expect(event.transactions[0].data).to.be.equal(proposalTransaction.data); - expect(event.transactions[0].operation).to.be.equal( - proposalTransaction.operation - ); + expect(event.transactions[0].operation).to.be.equal(proposalTransaction.operation); expect(event.metadata).to.be.equal(proposalMetadata); }); - it("A proposal can be created and executed", async () => { + it('A proposal can be created and executed', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [proposalTransaction], ''); - const txHash = await azorius.getTxHash( - await mockNFT1.getAddress(), - 0n, - mintNFTData, - 0 - ); + const txHash = await azorius.getTxHash(await mockNFT1.getAddress(), 0n, mintNFTData, 0); const proposalTxHashes = await azorius.getProposalTxHashes(0); @@ -835,29 +653,17 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect(await azorius.proposalState(0)).to.eq(0); // NFT ids haven't voted yet - expect( - await linearERC721Voting.hasVoted(0, await mockNFT1.getAddress(), 0) - ).to.eq(false); - expect( - await linearERC721Voting.hasVoted(0, await mockNFT2.getAddress(), 0) - ).to.eq(false); + expect(await linearERC721Voting.hasVoted(0, await mockNFT1.getAddress(), 0)).to.eq(false); + expect(await linearERC721Voting.hasVoted(0, await mockNFT2.getAddress(), 0)).to.eq(false); // Users vote in support of proposal - await linearERC721Voting - .connect(tokenHolder1) - .vote(0, 1, holder1Tokens, holder1Ids); + await linearERC721Voting.connect(tokenHolder1).vote(0, 1, holder1Tokens, holder1Ids); - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); // NFT ids have voted - expect( - await linearERC721Voting.hasVoted(0, await mockNFT1.getAddress(), 0) - ).to.eq(true); - expect( - await linearERC721Voting.hasVoted(0, await mockNFT2.getAddress(), 0) - ).to.eq(true); + expect(await linearERC721Voting.hasVoted(0, await mockNFT1.getAddress(), 0)).to.eq(true); + expect(await linearERC721Voting.hasVoted(0, await mockNFT2.getAddress(), 0)).to.eq(true); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -874,13 +680,7 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect(await mockNFT1.balanceOf(deployer.address)).to.eq(0); // Execute the transaction - await azorius.executeProposal( - 0, - [await mockNFT1.getAddress()], - [0], - [mintNFTData], - [0] - ); + await azorius.executeProposal(0, [await mockNFT1.getAddress()], [0], [mintNFTData], [0]); expect(await azorius.getProposal(0)).to.deep.eq([ await linearERC721Voting.getAddress(), @@ -896,7 +696,7 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect(await azorius.proposalState(0)).to.eq(3); }); - it("Multiple transactions can be executed from a single proposal", async () => { + it('Multiple transactions can be executed from a single proposal', async () => { // Create transaction to mint tokens to the deployer const tokenTransferData1 = mintNFTData; const tokenTransferData2 = mintNFTData; @@ -927,21 +727,17 @@ describe("Safe with Azorius module and linearERC721Voting", () => { .connect(tokenHolder2) .submitProposal( await linearERC721Voting.getAddress(), - "0x", + '0x', [proposalTransaction1, proposalTransaction2, proposalTransaction3], - "" + '', ); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // Users vote in support of proposal - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -960,14 +756,10 @@ describe("Safe with Azorius module and linearERC721Voting", () => { // Execute the transaction await azorius.executeProposal( 0, - [ - await mockNFT1.getAddress(), - await mockNFT1.getAddress(), - await mockNFT1.getAddress(), - ], + [await mockNFT1.getAddress(), await mockNFT1.getAddress(), await mockNFT1.getAddress()], [0, 0, 0], [tokenTransferData1, tokenTransferData2, tokenTransferData3], - [0, 0, 0] + [0, 0, 0], ); expect(await mockNFT1.balanceOf(deployer.address)).to.eq(3); @@ -976,26 +768,22 @@ describe("Safe with Azorius module and linearERC721Voting", () => { expect(await azorius.proposalState(0)).to.eq(3); }); - it("Executing a proposal reverts if the transaction cannot be executed", async () => { + it('Executing a proposal reverts if the transaction cannot be executed', async () => { await azorius .connect(tokenHolder2) .submitProposal( await linearERC721Voting.getAddress(), - "0x", + '0x', [await mockRevertTransaction()], - "" + '', ); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // Users vote in support of proposal - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1017,38 +805,27 @@ describe("Safe with Azorius module and linearERC721Voting", () => { [0], [ // eslint-disable-next-line camelcase - MockContract__factory.createInterface().encodeFunctionData( - "revertSomething" - ), + MockContract__factory.createInterface().encodeFunctionData('revertSomething'), ], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "TxFailed"); + [0], + ), + ).to.be.revertedWithCustomError(azorius, 'TxFailed'); // Proposal is executable expect(await azorius.proposalState(0)).to.eq(2); }); - it("If a proposal is not executed during the execution period, it becomes expired", async () => { + it('If a proposal is not executed during the execution period, it becomes expired', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [proposalTransaction], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [proposalTransaction], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // Users vote in support of proposal - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1070,20 +847,14 @@ describe("Safe with Azorius module and linearERC721Voting", () => { // Execute the transaction await expect( - azorius.executeProposal( - 0, - [await mockNFT1.getAddress()], - [0], - [mintNFTData], - [0] - ) - ).to.be.revertedWithCustomError(azorius, "ProposalNotExecutable"); + azorius.executeProposal(0, [await mockNFT1.getAddress()], [0], [mintNFTData], [0]), + ).to.be.revertedWithCustomError(azorius, 'ProposalNotExecutable'); }); - it("A proposal with no transactions that passes goes immediately to executed", async () => { + it('A proposal with no transactions that passes goes immediately to executed', async () => { await azorius .connect(tokenHolder2) - .submitProposal(await linearERC721Voting.getAddress(), "0x", [], ""); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); @@ -1091,12 +862,8 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await linearERC721Voting.isPassed(0)).to.be.false; // Users vote in support of proposal - await linearERC721Voting - .connect(tokenHolder2) - .vote(0, 1, holder2Tokens, holder2Ids); - await linearERC721Voting - .connect(tokenHolder3) - .vote(0, 1, holder3Tokens, holder3Ids); + await linearERC721Voting.connect(tokenHolder2).vote(0, 1, holder2Tokens, holder2Ids); + await linearERC721Voting.connect(tokenHolder3).vote(0, 1, holder3Tokens, holder3Ids); // Increase time so that voting period has ended await time.advanceBlocks(60); @@ -1107,210 +874,173 @@ describe("Safe with Azorius module and linearERC721Voting", () => { await expect(await azorius.proposalState(0)).to.eq(3); }); - it("Only the owner can update the timelock period on Azorius", async () => { + it('Only the owner can update the timelock period on Azorius', async () => { expect(await azorius.timelockPeriod()).to.eq(60); await azorius.connect(gnosisSafeOwner).updateTimelockPeriod(70); expect(await azorius.timelockPeriod()).to.eq(70); - await expect( - azorius.connect(tokenHolder1).updateTimelockPeriod(80) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(azorius.connect(tokenHolder1).updateTimelockPeriod(80)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the owner can update the execution period on Azorius", async () => { + it('Only the owner can update the execution period on Azorius', async () => { expect(await azorius.executionPeriod()).to.eq(60); await azorius.connect(gnosisSafeOwner).updateExecutionPeriod(100); expect(await azorius.executionPeriod()).to.eq(100); - await expect( - azorius.connect(tokenHolder1).updateExecutionPeriod(110) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(azorius.connect(tokenHolder1).updateExecutionPeriod(110)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the owner can update the quorum threshold on the ERC721LinearVoting", async () => { + it('Only the owner can update the quorum threshold on the ERC721LinearVoting', async () => { expect(await linearERC721Voting.quorumThreshold()).to.eq(2); - await linearERC721Voting - .connect(gnosisSafeOwner) - .updateQuorumThreshold(4); + await linearERC721Voting.connect(gnosisSafeOwner).updateQuorumThreshold(4); expect(await linearERC721Voting.quorumThreshold()).to.eq(4); await expect( - linearERC721Voting.connect(tokenHolder1).updateQuorumThreshold(5) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC721Voting.connect(tokenHolder1).updateQuorumThreshold(5), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Only the owner can update the basis numerator on the ERC721LinearVoting", async () => { + it('Only the owner can update the basis numerator on the ERC721LinearVoting', async () => { expect(await linearERC721Voting.basisNumerator()).to.eq(500000); - await linearERC721Voting - .connect(gnosisSafeOwner) - .updateBasisNumerator(600000); + await linearERC721Voting.connect(gnosisSafeOwner).updateBasisNumerator(600000); expect(await linearERC721Voting.basisNumerator()).to.eq(600000); await expect( - linearERC721Voting.connect(tokenHolder1).updateBasisNumerator(700000) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC721Voting.connect(tokenHolder1).updateBasisNumerator(700000), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Basis numerator cannot be updated to a value larger than the denominator", async () => { + it('Basis numerator cannot be updated to a value larger than the denominator', async () => { await expect( - linearERC721Voting - .connect(gnosisSafeOwner) - .updateBasisNumerator(1000001) - ).to.be.revertedWithCustomError( - linearERC721Voting, - "InvalidBasisNumerator" - ); + linearERC721Voting.connect(gnosisSafeOwner).updateBasisNumerator(1000001), + ).to.be.revertedWithCustomError(linearERC721Voting, 'InvalidBasisNumerator'); }); - it("Only the owner can update the proposer weight on the ERC721LinearVoting", async () => { + it('Only the owner can update the proposer weight on the ERC721LinearVoting', async () => { expect(await linearERC721Voting.proposerThreshold()).to.eq(2); - await linearERC721Voting - .connect(gnosisSafeOwner) - .updateProposerThreshold(2); + await linearERC721Voting.connect(gnosisSafeOwner).updateProposerThreshold(2); expect(await linearERC721Voting.proposerThreshold()).to.eq(2); await expect( - linearERC721Voting.connect(tokenHolder1).updateProposerThreshold(3) - ).to.be.revertedWith("Ownable: caller is not the owner"); + linearERC721Voting.connect(tokenHolder1).updateProposerThreshold(3), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Linear ERC721 voting contract cannot be setup with an invalid governance token address", async () => { + it('Linear ERC721 voting contract cannot be setup with an invalid governance token address', async () => { // Deploy Linear ERC721 Voting Strategy - linearERC721Voting = await new LinearERC721Voting__factory( - deployer - ).deploy(); + linearERC721Voting = await new LinearERC721Voting__factory(deployer).deploy(); const linearERC721VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC721Voting__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - [ - "address", - "address[]", - "uint256[]", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], - [ - gnosisSafeOwner.address, // owner - [ethers.ZeroAddress], // NFT addresses - [1], // NFT weights - await azorius.getAddress(), // Azorius module - 60, // voting period in blocks - 1, // quorom threshold - 1, // proposer threshold - 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] - ), - ] - ); + LinearERC721Voting__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + [ + 'address', + 'address[]', + 'uint256[]', + 'address', + 'uint32', + 'uint256', + 'uint256', + 'uint256', + ], + [ + gnosisSafeOwner.address, // owner + [ethers.ZeroAddress], // NFT addresses + [1], // NFT weights + await azorius.getAddress(), // Azorius module + 60, // voting period in blocks + 1, // quorom threshold + 1, // proposer threshold + 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) + ], + ), + ]); await expect( moduleProxyFactory.deployModule( await linearERC721VotingMastercopy.getAddress(), linearERC721VotingSetupCalldata, - "10031021" - ) + '10031021', + ), ).to.be.reverted; }); - it("An invalid vote type cannot be cast", async () => { + it('An invalid vote type cannot be cast', async () => { await azorius .connect(tokenHolder2) - .submitProposal( - await linearERC721Voting.getAddress(), - "0x", - [await mockTransaction()], - "" - ); + .submitProposal(await linearERC721Voting.getAddress(), '0x', [await mockTransaction()], ''); // Proposal is active expect(await azorius.proposalState(0)).to.eq(0); // Users cast invalid vote types await expect( - linearERC721Voting - .connect(tokenHolder2) - .vote(0, 3, holder2Tokens, holder2Ids) - ).to.be.revertedWithCustomError(linearERC721Voting, "InvalidVote"); + linearERC721Voting.connect(tokenHolder2).vote(0, 3, holder2Tokens, holder2Ids), + ).to.be.revertedWithCustomError(linearERC721Voting, 'InvalidVote'); await expect( - linearERC721Voting - .connect(tokenHolder2) - .vote(0, 4, holder2Tokens, holder2Ids) - ).to.be.revertedWithCustomError(linearERC721Voting, "InvalidVote"); + linearERC721Voting.connect(tokenHolder2).vote(0, 4, holder2Tokens, holder2Ids), + ).to.be.revertedWithCustomError(linearERC721Voting, 'InvalidVote'); await expect( - linearERC721Voting - .connect(tokenHolder2) - .vote(0, 5, holder2Tokens, holder2Ids) - ).to.be.revertedWithCustomError(linearERC721Voting, "InvalidVote"); + linearERC721Voting.connect(tokenHolder2).vote(0, 5, holder2Tokens, holder2Ids), + ).to.be.revertedWithCustomError(linearERC721Voting, 'InvalidVote'); }); it("A non-proposer can't submit a proposal", async () => { - expect(await linearERC721Voting.isProposer(tokenHolder2.address)).to.eq( - true - ); - expect(await linearERC721Voting.isProposer(deployer.address)).to.eq( - false - ); + expect(await linearERC721Voting.isProposer(tokenHolder2.address)).to.eq(true); + expect(await linearERC721Voting.isProposer(deployer.address)).to.eq(false); await expect( azorius .connect(deployer) .submitProposal( await linearERC721Voting.getAddress(), - "0x", + '0x', [await mockTransaction()], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer"); + '', + ), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer'); - await linearERC721Voting - .connect(gnosisSafeOwner) - .updateProposerThreshold(301); + await linearERC721Voting.connect(gnosisSafeOwner).updateProposerThreshold(301); - expect(await linearERC721Voting.isProposer(tokenHolder2.address)).to.eq( - false - ); - expect(await linearERC721Voting.isProposer(deployer.address)).to.eq( - false - ); + expect(await linearERC721Voting.isProposer(tokenHolder2.address)).to.eq(false); + expect(await linearERC721Voting.isProposer(deployer.address)).to.eq(false); await expect( azorius .connect(deployer) .submitProposal( await linearERC721Voting.getAddress(), - "0x", + '0x', [await mockTransaction()], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer"); + '', + ), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer'); await expect( azorius .connect(tokenHolder2) .submitProposal( await linearERC721Voting.getAddress(), - "0x", + '0x', [await mockTransaction()], - "" - ) - ).to.be.revertedWithCustomError(azorius, "InvalidProposer"); + '', + ), + ).to.be.revertedWithCustomError(azorius, 'InvalidProposer'); }); it("An proposal that hasn't been submitted yet is not passed", async () => { diff --git a/test/AzoriusFreezeGuard-ERC20FreezeVoting.test.ts b/test/AzoriusFreezeGuard-ERC20FreezeVoting.test.ts index cce6dd60..38a13082 100644 --- a/test/AzoriusFreezeGuard-ERC20FreezeVoting.test.ts +++ b/test/AzoriusFreezeGuard-ERC20FreezeVoting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { GnosisSafe, @@ -19,23 +17,24 @@ import { VotesERC20__factory, ModuleProxyFactory, GnosisSafeL2__factory, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, safeSignTypedData, predictGnosisSafeAddress, calculateProxyAddress, -} from "./helpers"; +} from './helpers'; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, -} from "./GlobalSafeDeployments.test"; +import time from './time'; -describe("Azorius Child DAO with Azorius Parent", () => { +describe('Azorius Child DAO with Azorius Parent', () => { // Deployed contracts let childGnosisSafe: GnosisSafe; let freezeGuardMastercopy: AzoriusFreezeGuard; @@ -64,9 +63,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Gnosis let createGnosisSetupCalldata: string; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); @@ -88,7 +85,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ [childSafeOwner.address], 1, ethers.ZeroAddress, @@ -103,123 +100,109 @@ describe("Azorius Child DAO with Azorius Parent", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, - saltNum + saltNum, ); // Get module proxy factory moduleProxyFactory = await hre.ethers.getContractAt( - "ModuleProxyFactory", - await moduleProxyFactory.getAddress() + 'ModuleProxyFactory', + await moduleProxyFactory.getAddress(), ); - childGnosisSafe = await hre.ethers.getContractAt( - "GnosisSafe", - predictedGnosisSafeAddress - ); + childGnosisSafe = await hre.ethers.getContractAt('GnosisSafe', predictedGnosisSafeAddress); // Deploy Votes ERC20 Mastercopy votesERC20Mastercopy = await new VotesERC20__factory(deployer).deploy(); const childVotesERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "CHILD", - "CHILD", + 'CHILD', + 'CHILD', [ childTokenHolder1.address, childTokenHolder2.address, await childGnosisSafe.getAddress(), ], [100, 100, 100], - ] + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), childVotesERC20SetupData, - "10031021" + '10031021', ); const predictedChildVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), childVotesERC20SetupData, - "10031021" + '10031021', ); - childVotesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedChildVotesERC20Address - ); + childVotesERC20 = await hre.ethers.getContractAt('VotesERC20', predictedChildVotesERC20Address); // Parent Votes ERC-20 parentVotesERC20 = await new VotesERC20__factory(deployer).deploy(); const parentVotesERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "PARENT", - "PARENT", + 'PARENT', + 'PARENT', [parentTokenHolder1.address, parentTokenHolder2.address], [100, 100], - ] + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), parentVotesERC20SetupData, - "10031021" + '10031021', ); const predictedParentVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), parentVotesERC20SetupData, - "10031021" + '10031021', ); parentVotesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedParentVotesERC20Address + 'VotesERC20', + predictedParentVotesERC20Address, ); // Token holders delegate their votes to themselves - await childVotesERC20 - .connect(childTokenHolder1) - .delegate(childTokenHolder1.address); - await childVotesERC20 - .connect(childTokenHolder2) - .delegate(childTokenHolder2.address); - await parentVotesERC20 - .connect(parentTokenHolder1) - .delegate(parentTokenHolder1.address); - await parentVotesERC20 - .connect(parentTokenHolder2) - .delegate(parentTokenHolder2.address); + await childVotesERC20.connect(childTokenHolder1).delegate(childTokenHolder1.address); + await childVotesERC20.connect(childTokenHolder2).delegate(childTokenHolder2.address); + await parentVotesERC20.connect(parentTokenHolder1).delegate(parentTokenHolder1.address); + await parentVotesERC20.connect(parentTokenHolder2).delegate(parentTokenHolder2.address); // Deploy Azorius module azoriusMastercopy = await new Azorius__factory(deployer).deploy(); const azoriusSetupCalldata = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ + Azorius__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ mockParentDAO.address, await childGnosisSafe.getAddress(), @@ -227,46 +210,33 @@ describe("Azorius Child DAO with Azorius Parent", () => { [], 60, // Timelock period in blocks 60, // Execution period in blocks - ] + ], ), ]); await moduleProxyFactory.deployModule( await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); const predictedAzoriusAddress = await calculateProxyAddress( moduleProxyFactory, await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); - azoriusModule = await hre.ethers.getContractAt( - "Azorius", - predictedAzoriusAddress - ); + azoriusModule = await hre.ethers.getContractAt('Azorius', predictedAzoriusAddress); // Deploy Linear ERC-20 Voting Strategy - linearERC20VotingMastercopy = await new LinearERC20Voting__factory( - deployer - ).deploy(); + linearERC20VotingMastercopy = await new LinearERC20Voting__factory(deployer).deploy(); const linearERC20VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC20Voting__factory.createInterface().encodeFunctionData("setUp", [ + LinearERC20Voting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - [ - "address", - "address", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], + ['address', 'address', 'address', 'uint32', 'uint256', 'uint256', 'uint256'], [ mockParentDAO.address, // owner await childVotesERC20.getAddress(), // governance token @@ -275,116 +245,104 @@ describe("Azorius Child DAO with Azorius Parent", () => { 0, // proposer weight 500000, // quorom numerator, denominator is 1,000,000 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] + ], ), ]); await moduleProxyFactory.deployModule( await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" + '10031021', ); const predictedLinearERC20VotingAddress = await calculateProxyAddress( moduleProxyFactory, await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" + '10031021', ); linearERC20Voting = await hre.ethers.getContractAt( - "LinearERC20Voting", - predictedLinearERC20VotingAddress + 'LinearERC20Voting', + predictedLinearERC20VotingAddress, ); // Enable the Linear Token Voting strategy on Azorius - await azoriusModule - .connect(mockParentDAO) - .enableStrategy(await linearERC20Voting.getAddress()); + await azoriusModule.connect(mockParentDAO).enableStrategy(await linearERC20Voting.getAddress()); // Deploy ERC20FreezeVoting contract - freezeVotingMastercopy = await new ERC20FreezeVoting__factory( - deployer - ).deploy(); + freezeVotingMastercopy = await new ERC20FreezeVoting__factory(deployer).deploy(); const freezeVotingSetupCalldata = // eslint-disable-next-line camelcase - ERC20FreezeVoting__factory.createInterface().encodeFunctionData("setUp", [ + ERC20FreezeVoting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "uint256", "uint32", "uint32", "address"], + ['address', 'uint256', 'uint32', 'uint32', 'address'], [ mockParentDAO.address, // owner 150, // freeze votes threshold 10, // freeze proposal duration in blocks 100, // freeze duration in blocks await parentVotesERC20.getAddress(), - ] + ], ), ]); await moduleProxyFactory.deployModule( await freezeVotingMastercopy.getAddress(), freezeVotingSetupCalldata, - "10031021" + '10031021', ); const predictedFreezeVotingAddress = await calculateProxyAddress( moduleProxyFactory, await freezeVotingMastercopy.getAddress(), freezeVotingSetupCalldata, - "10031021" + '10031021', ); freezeVoting = await hre.ethers.getContractAt( - "ERC20FreezeVoting", - predictedFreezeVotingAddress + 'ERC20FreezeVoting', + predictedFreezeVotingAddress, ); // Deploy and setUp Azorius Freeze Guard contract - freezeGuardMastercopy = await new AzoriusFreezeGuard__factory( - deployer - ).deploy(); + freezeGuardMastercopy = await new AzoriusFreezeGuard__factory(deployer).deploy(); const freezeGuardSetupCalldata = // eslint-disable-next-line camelcase - LinearERC20Voting__factory.createInterface().encodeFunctionData("setUp", [ + LinearERC20Voting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address"], + ['address', 'address'], [ mockParentDAO.address, // Owner await freezeVoting.getAddress(), // Freeze voting contract - ] + ], ), ]); await moduleProxyFactory.deployModule( await freezeGuardMastercopy.getAddress(), freezeGuardSetupCalldata, - "10031021" + '10031021', ); const predictedFreezeGuardAddress = await calculateProxyAddress( moduleProxyFactory, await freezeGuardMastercopy.getAddress(), freezeGuardSetupCalldata, - "10031021" + '10031021', ); - freezeGuard = await hre.ethers.getContractAt( - "AzoriusFreezeGuard", - predictedFreezeGuardAddress - ); + freezeGuard = await hre.ethers.getContractAt('AzoriusFreezeGuard', predictedFreezeGuardAddress); // Set the Azorius Freeze Guard as the Guard on the Azorius Module - await azoriusModule - .connect(mockParentDAO) - .setGuard(await freezeGuard.getAddress()); + await azoriusModule.connect(mockParentDAO).setGuard(await freezeGuard.getAddress()); // Create transaction on Gnosis Safe to setup Azorius module - const enableAzoriusModuleData = - childGnosisSafe.interface.encodeFunctionData("enableModule", [ - await azoriusModule.getAddress(), - ]); + const enableAzoriusModuleData = childGnosisSafe.interface.encodeFunctionData('enableModule', [ + await azoriusModule.getAddress(), + ]); const enableAzoriusModuleTx = buildSafeTransaction({ to: await childGnosisSafe.getAddress(), @@ -393,13 +351,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { nonce: await childGnosisSafe.nonce(), }); - const sigs = [ - await safeSignTypedData( - childSafeOwner, - childGnosisSafe, - enableAzoriusModuleTx - ), - ]; + const sigs = [await safeSignTypedData(childSafeOwner, childGnosisSafe, enableAzoriusModuleTx)]; const signatureBytes = buildSignatureBytes(sigs); @@ -415,23 +367,21 @@ describe("Azorius Child DAO with Azorius Parent", () => { enableAzoriusModuleTx.gasPrice, enableAzoriusModuleTx.gasToken, enableAzoriusModuleTx.refundReceiver, - signatureBytes - ) - ).to.emit(childGnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(childGnosisSafe, 'ExecutionSuccess'); // Gnosis Safe received the 1,000 tokens - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); }); - describe("FreezeGuard Functionality", () => { - it("A proposal can be created and executed", async () => { + describe('FreezeGuard Functionality', () => { + it('A proposal can be created and executed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); const proposalTransaction = { to: await childVotesERC20.getAddress(), @@ -442,9 +392,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction], - "" + '', ); // Proposal is active @@ -466,9 +416,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Proposal is executable expect(await azoriusModule.proposalState(0)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -477,34 +425,32 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData], - [0] + [0], ); // Proposal is executed expect(await azoriusModule.proposalState(0)).to.eq(3); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(90); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(90); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(10); }); - it("A proposal containing multiple transactions can be created and executed", async () => { + it('A proposal containing multiple transactions can be created and executed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 2] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 2, + ]); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 3] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 3, + ]); const proposalTransactions = [ { @@ -529,9 +475,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', proposalTransactions, - "" + '', ); // Proposal is active @@ -550,9 +496,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Proposal is executable expect(await azoriusModule.proposalState(0)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -565,35 +509,33 @@ describe("Azorius Child DAO with Azorius Parent", () => { ], [0, 0, 0], [tokenTransferData1, tokenTransferData2, tokenTransferData3], - [0, 0, 0] + [0, 0, 0], ); // Proposal is executed expect(await azoriusModule.proposalState(0)).to.eq(3); // Check that all three token transfer TX's were executed - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(94); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(94); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(6); }); - it("A frozen DAO cannot execute any transaction", async () => { + it('A frozen DAO cannot execute any transaction', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 5] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 5, + ]); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 4] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 4, + ]); const proposalTransaction1 = { to: await childVotesERC20.getAddress(), @@ -618,21 +560,21 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction2], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction3], - "" + '', ); // Proposal is active @@ -682,9 +624,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -693,9 +635,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -704,18 +646,18 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData3], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); }); }); - it("A proposal can still be executed if a freeze proposal has been created, but threshold has not been met", async () => { + it('A proposal can still be executed if a freeze proposal has been created, but threshold has not been met', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); const proposalTransaction = { to: await childVotesERC20.getAddress(), @@ -726,9 +668,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction], - "" + '', ); // Proposal is active @@ -757,9 +699,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Proposal is ready to execute expect(await azoriusModule.proposalState(0)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -768,29 +708,27 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData], - [0] + [0], ); // Proposal is executed expect(await azoriusModule.proposalState(0)).to.eq(3); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(90); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(90); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(10); }); - it("A frozen DAO is automatically unfrozen after the freeze duration is over", async () => { + it('A frozen DAO is automatically unfrozen after the freeze duration is over', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 5] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 5, + ]); const proposalTransaction1 = { to: await childVotesERC20.getAddress(), @@ -808,15 +746,15 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction2], - "" + '', ); // Proposal is active @@ -859,9 +797,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -870,19 +808,19 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Increase time so that freeze has ended for (let i = 0; i <= 100; i++) { - await hre.network.provider.send("evm_mine"); + await hre.network.provider.send('evm_mine'); } - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 4] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 4, + ]); const proposalTransaction3 = { to: await childVotesERC20.getAddress(), @@ -893,9 +831,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction3], - "" + '', ); expect(await azoriusModule.proposalState(2)).to.eq(0); @@ -915,9 +853,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Proposal is ready to execute expect(await azoriusModule.proposalState(2)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -926,34 +862,32 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData3], - [0] + [0], ); // Proposal is executed expect(await azoriusModule.proposalState(2)).to.eq(3); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(96); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(96); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(4); }); it("A frozen DAO can be unfrozen by its owner, and continue to execute TX's", async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 5] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 5, + ]); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 4] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 4, + ]); const proposalTransaction1 = { to: await childVotesERC20.getAddress(), @@ -978,23 +912,23 @@ describe("Azorius Child DAO with Azorius Parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction2], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction3], - "" + '', ); // Proposal is active @@ -1044,9 +978,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -1055,9 +989,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -1066,9 +1000,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData3], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Parent DAO unfreezes the child await freezeVoting.connect(mockParentDAO).unfreeze(); @@ -1076,9 +1010,7 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Child DAO is now unfrozen expect(await freezeVoting.isFrozen()).to.eq(false); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -1087,16 +1019,14 @@ describe("Azorius Child DAO with Azorius Parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] + [0], ); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(90); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(90); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(10); }); - it("Freeze state values are updated correctly throughout the freeze process", async () => { + it('Freeze state values are updated correctly throughout the freeze process', async () => { // freeze votes threshold => 150 // freeze proposal duration in blocks => 10 // freeze duration in blocks => 100 @@ -1104,12 +1034,8 @@ describe("Azorius Child DAO with Azorius Parent", () => { // One voter casts freeze vote await freezeVoting.connect(parentTokenHolder1).castFreezeVote(); - const firstFreezeProposalCreatedBlock = (await hre.ethers.provider.getBlock( - "latest" - ))!.number; - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - firstFreezeProposalCreatedBlock - ); + const firstFreezeProposalCreatedBlock = (await hre.ethers.provider.getBlock('latest'))!.number; + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(firstFreezeProposalCreatedBlock); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(100); @@ -1118,14 +1044,14 @@ describe("Azorius Child DAO with Azorius Parent", () => { expect( await freezeVoting.userHasFreezeVoted( parentTokenHolder1.address, - firstFreezeProposalCreatedBlock - ) + firstFreezeProposalCreatedBlock, + ), ).to.eq(true); expect( await freezeVoting.userHasFreezeVoted( parentTokenHolder2.address, - firstFreezeProposalCreatedBlock - ) + firstFreezeProposalCreatedBlock, + ), ).to.eq(false); // Increase time so freeze proposal has ended @@ -1134,12 +1060,9 @@ describe("Azorius Child DAO with Azorius Parent", () => { // One voter casts freeze vote, this should create a new freeze proposal await freezeVoting.connect(parentTokenHolder1).castFreezeVote(); - const secondFreezeProposalCreatedBlock = - (await hre.ethers.provider.getBlock("latest"))!.number; + const secondFreezeProposalCreatedBlock = (await hre.ethers.provider.getBlock('latest'))!.number; - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - secondFreezeProposalCreatedBlock - ); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(secondFreezeProposalCreatedBlock); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(100); @@ -1148,27 +1071,25 @@ describe("Azorius Child DAO with Azorius Parent", () => { expect( await freezeVoting.userHasFreezeVoted( parentTokenHolder1.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(true); expect( await freezeVoting.userHasFreezeVoted( parentTokenHolder2.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(false); // First voter cannot vote again await expect( - freezeVoting.connect(parentTokenHolder1).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "AlreadyVoted"); + freezeVoting.connect(parentTokenHolder1).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'AlreadyVoted'); // Second voter casts freeze vote, should update state of current freeze proposal await freezeVoting.connect(parentTokenHolder2).castFreezeVote(); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - secondFreezeProposalCreatedBlock - ); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(secondFreezeProposalCreatedBlock); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(200); @@ -1177,14 +1098,14 @@ describe("Azorius Child DAO with Azorius Parent", () => { expect( await freezeVoting.userHasFreezeVoted( parentTokenHolder1.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(true); expect( await freezeVoting.userHasFreezeVoted( parentTokenHolder2.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(true); // Move time forward, freeze should still be active @@ -1195,27 +1116,25 @@ describe("Azorius Child DAO with Azorius Parent", () => { // Move time forward, freeze should end await time.advanceBlocks(10); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - secondFreezeProposalCreatedBlock - ); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(secondFreezeProposalCreatedBlock); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(200); expect(await freezeVoting.isFrozen()).to.eq(false); }); - it("A user with no freeze votes cannot cast freeze votes", async () => { + it('A user with no freeze votes cannot cast freeze votes', async () => { // User has no freeze votes await expect( - freezeVoting.connect(childTokenHolder1).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + freezeVoting.connect(childTokenHolder1).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); // Freeze proposal is created await freezeVoting.connect(parentTokenHolder1).castFreezeVote(); // User has no freeze votes await expect( - freezeVoting.connect(childTokenHolder1).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + freezeVoting.connect(childTokenHolder1).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); }); }); diff --git a/test/AzoriusFreezeGuard-MultisigFreezeVoting.test.ts b/test/AzoriusFreezeGuard-MultisigFreezeVoting.test.ts index ead4aea4..a480bb44 100644 --- a/test/AzoriusFreezeGuard-MultisigFreezeVoting.test.ts +++ b/test/AzoriusFreezeGuard-MultisigFreezeVoting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { GnosisSafeProxyFactory, @@ -19,23 +17,24 @@ import { ModuleProxyFactory, GnosisSafeL2__factory, GnosisSafeL2, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, safeSignTypedData, predictGnosisSafeAddress, calculateProxyAddress, -} from "./helpers"; +} from './helpers'; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, -} from "./GlobalSafeDeployments.test"; +import time from './time'; -describe("Azorius Child DAO with Multisig parent", () => { +describe('Azorius Child DAO with Multisig parent', () => { // Deployed contracts let parentGnosisSafe: GnosisSafeL2; let childGnosisSafe: GnosisSafeL2; @@ -68,9 +67,7 @@ describe("Azorius Child DAO with Multisig parent", () => { let createParentGnosisSetupCalldata: string; const parentThreshold = 2; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); @@ -94,12 +91,8 @@ describe("Azorius Child DAO with Multisig parent", () => { createParentGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [ - parentMultisigOwner1.address, - parentMultisigOwner2.address, - parentMultisigOwner3.address, - ], + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ + [parentMultisigOwner1.address, parentMultisigOwner2.address, parentMultisigOwner3.address], parentThreshold, ethers.ZeroAddress, ethers.ZeroHash, @@ -111,7 +104,7 @@ describe("Azorius Child DAO with Multisig parent", () => { createChildGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ [childSafeOwner.address], 1, ethers.ZeroAddress, @@ -126,40 +119,40 @@ describe("Azorius Child DAO with Multisig parent", () => { createParentGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); const predictedChildGnosisSafeAddress = await predictGnosisSafeAddress( createChildGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Parent Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createParentGnosisSetupCalldata, - saltNum + saltNum, ); // Deploy Child Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createChildGnosisSetupCalldata, - saltNum + saltNum, ); // Get Parent Gnosis Safe parentGnosisSafe = await hre.ethers.getContractAt( - "GnosisSafeL2", - predictedParentGnosisSafeAddress + 'GnosisSafeL2', + predictedParentGnosisSafeAddress, ); // Get Child Gnosis Safe childGnosisSafe = await hre.ethers.getContractAt( - "GnosisSafeL2", - predictedChildGnosisSafeAddress + 'GnosisSafeL2', + predictedChildGnosisSafeAddress, ); // Deploy Votes ERC-20 Mastercopy @@ -167,19 +160,19 @@ describe("Azorius Child DAO with Multisig parent", () => { const childVotesERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "CHILD", - "CHILD", + 'CHILD', + 'CHILD', [ childTokenHolder1.address, childTokenHolder2.address, await childGnosisSafe.getAddress(), ], [100, 100, 100], - ] + ], ), ]); @@ -188,37 +181,30 @@ describe("Azorius Child DAO with Multisig parent", () => { await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), childVotesERC20SetupData, - "10031021" + '10031021', ); const predictedChildVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), childVotesERC20SetupData, - "10031021" + '10031021', ); - childVotesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedChildVotesERC20Address - ); + childVotesERC20 = await hre.ethers.getContractAt('VotesERC20', predictedChildVotesERC20Address); // Token holders delegate their votes to themselves - await childVotesERC20 - .connect(childTokenHolder1) - .delegate(childTokenHolder1.address); - await childVotesERC20 - .connect(childTokenHolder2) - .delegate(childTokenHolder2.address); + await childVotesERC20.connect(childTokenHolder1).delegate(childTokenHolder1.address); + await childVotesERC20.connect(childTokenHolder2).delegate(childTokenHolder2.address); // Deploy Azorius module mastercopy azoriusMastercopy = await new Azorius__factory(deployer).deploy(); const azoriusSetupCalldata = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ + Azorius__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ azoriusModuleOwner.address, await childGnosisSafe.getAddress(), @@ -226,46 +212,33 @@ describe("Azorius Child DAO with Multisig parent", () => { [], 60, // Timelock period in blocks 60, // Execution period in blocks - ] + ], ), ]); await moduleProxyFactory.deployModule( await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); const predictedAzoriusAddress = await calculateProxyAddress( moduleProxyFactory, await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); - azoriusModule = await hre.ethers.getContractAt( - "Azorius", - predictedAzoriusAddress - ); + azoriusModule = await hre.ethers.getContractAt('Azorius', predictedAzoriusAddress); // Deploy Linear ERC-20 Voting Strategy Mastercopy - linearERC20VotingMastercopy = await new LinearERC20Voting__factory( - deployer - ).deploy(); + linearERC20VotingMastercopy = await new LinearERC20Voting__factory(deployer).deploy(); const linearERC20VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC20Voting__factory.createInterface().encodeFunctionData("setUp", [ + LinearERC20Voting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - [ - "address", - "address", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], + ['address', 'address', 'address', 'uint32', 'uint256', 'uint256', 'uint256'], [ await parentGnosisSafe.getAddress(), // owner await childVotesERC20.getAddress(), // governance token @@ -274,26 +247,26 @@ describe("Azorius Child DAO with Multisig parent", () => { 0, // proposer weight 500000, // quorom numerator, denominator is 1,000,000 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] + ], ), ]); await moduleProxyFactory.deployModule( await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" + '10031021', ); const predictedLinearERC20VotingAddress = await calculateProxyAddress( moduleProxyFactory, await linearERC20VotingMastercopy.getAddress(), linearERC20VotingSetupCalldata, - "10031021" + '10031021', ); linearERC20Voting = await hre.ethers.getContractAt( - "LinearERC20Voting", - predictedLinearERC20VotingAddress + 'LinearERC20Voting', + predictedLinearERC20VotingAddress, ); // Enable the Linear Token Voting strategy on Azorius @@ -302,86 +275,75 @@ describe("Azorius Child DAO with Multisig parent", () => { .enableStrategy(await linearERC20Voting.getAddress()); // Deploy MultisigFreezeVoting mastercopy contract - freezeVotingMastercopy = await new MultisigFreezeVoting__factory( - deployer - ).deploy(); + freezeVotingMastercopy = await new MultisigFreezeVoting__factory(deployer).deploy(); const freezeVotingSetupCalldata = // eslint-disable-next-line camelcase - MultisigFreezeVoting__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["address", "uint256", "uint32", "uint32", "address"], - [ - freezeVotingOwner.address, // owner - 2, // freeze votes threshold - 10, // freeze proposal duration in blocks - 200, // freeze duration in blocks - await parentGnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeVoting__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['address', 'uint256', 'uint32', 'uint32', 'address'], + [ + freezeVotingOwner.address, // owner + 2, // freeze votes threshold + 10, // freeze proposal duration in blocks + 200, // freeze duration in blocks + await parentGnosisSafe.getAddress(), + ], + ), + ]); await moduleProxyFactory.deployModule( await freezeVotingMastercopy.getAddress(), freezeVotingSetupCalldata, - "10031021" + '10031021', ); const predictedFreezeVotingAddress = await calculateProxyAddress( moduleProxyFactory, await freezeVotingMastercopy.getAddress(), freezeVotingSetupCalldata, - "10031021" + '10031021', ); freezeVoting = await hre.ethers.getContractAt( - "MultisigFreezeVoting", - predictedFreezeVotingAddress + 'MultisigFreezeVoting', + predictedFreezeVotingAddress, ); // Deploy and setUp AzoriusFreezeGuard mastercopy contract - freezeGuardMastercopy = await new AzoriusFreezeGuard__factory( - deployer - ).deploy(); + freezeGuardMastercopy = await new AzoriusFreezeGuard__factory(deployer).deploy(); const freezeGuardSetupCalldata = // eslint-disable-next-line camelcase - LinearERC20Voting__factory.createInterface().encodeFunctionData("setUp", [ + LinearERC20Voting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address"], + ['address', 'address'], [ freezeVotingOwner.address, // owner await freezeVoting.getAddress(), // freeze voting contract - ] + ], ), ]); await moduleProxyFactory.deployModule( await freezeGuardMastercopy.getAddress(), freezeGuardSetupCalldata, - "10031021" + '10031021', ); const predictedFreezeGuardAddress = await calculateProxyAddress( moduleProxyFactory, await freezeGuardMastercopy.getAddress(), freezeGuardSetupCalldata, - "10031021" + '10031021', ); - freezeGuard = await hre.ethers.getContractAt( - "AzoriusFreezeGuard", - predictedFreezeGuardAddress - ); + freezeGuard = await hre.ethers.getContractAt('AzoriusFreezeGuard', predictedFreezeGuardAddress); // Create transaction on child Gnosis Safe to setup Azorius module - const enableAzoriusModuleData = - childGnosisSafe.interface.encodeFunctionData("enableModule", [ - await azoriusModule.getAddress(), - ]); + const enableAzoriusModuleData = childGnosisSafe.interface.encodeFunctionData('enableModule', [ + await azoriusModule.getAddress(), + ]); const enableAzoriusModuleTx = buildSafeTransaction({ to: await childGnosisSafe.getAddress(), @@ -390,13 +352,7 @@ describe("Azorius Child DAO with Multisig parent", () => { nonce: await childGnosisSafe.nonce(), }); - const sigs = [ - await safeSignTypedData( - childSafeOwner, - childGnosisSafe, - enableAzoriusModuleTx - ), - ]; + const sigs = [await safeSignTypedData(childSafeOwner, childGnosisSafe, enableAzoriusModuleTx)]; const signatureBytes = buildSignatureBytes(sigs); @@ -412,28 +368,24 @@ describe("Azorius Child DAO with Multisig parent", () => { enableAzoriusModuleTx.gasPrice, enableAzoriusModuleTx.gasToken, enableAzoriusModuleTx.refundReceiver, - signatureBytes - ) - ).to.emit(childGnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(childGnosisSafe, 'ExecutionSuccess'); // Set the Azorius Freeze Guard as the Guard on the Azorius Module - await azoriusModule - .connect(azoriusModuleOwner) - .setGuard(await freezeGuard.getAddress()); + await azoriusModule.connect(azoriusModuleOwner).setGuard(await freezeGuard.getAddress()); // Gnosis Safe received the 100 tokens - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); }); - describe("AzoriusFreezeGuard Functionality", () => { - it("A proposal can be created and executed", async () => { + describe('AzoriusFreezeGuard Functionality', () => { + it('A proposal can be created and executed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); const proposalTransaction = { to: await childVotesERC20.getAddress(), @@ -444,9 +396,9 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction], - "" + '', ); // Proposal is active @@ -468,9 +420,7 @@ describe("Azorius Child DAO with Multisig parent", () => { // Proposal is ready to execute expect(await azoriusModule.proposalState(0)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -479,31 +429,29 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData], - [0] + [0], ); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(90); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(90); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(10); }); - it("A proposal containing multiple transactions can be created and executed", async () => { + it('A proposal containing multiple transactions can be created and executed', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 2] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 2, + ]); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 3] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 3, + ]); const proposalTransactions = [ { @@ -528,9 +476,9 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', proposalTransactions, - "" + '', ); // Proposal is active @@ -552,9 +500,7 @@ describe("Azorius Child DAO with Multisig parent", () => { // Proposal is ready to execute expect(await azoriusModule.proposalState(0)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -567,32 +513,30 @@ describe("Azorius Child DAO with Multisig parent", () => { ], [0, 0, 0], [tokenTransferData1, tokenTransferData2, tokenTransferData3], - [0, 0, 0] + [0, 0, 0], ); // Check that all three token transfer TX's were executed - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(94); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(94); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(6); }); - it("A frozen DAO cannot execute any transaction", async () => { + it('A frozen DAO cannot execute any transaction', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 5] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 5, + ]); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 4] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 4, + ]); const proposalTransaction1 = { to: await childVotesERC20.getAddress(), @@ -617,21 +561,21 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction2], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction3], - "" + '', ); // Proposal is active @@ -681,9 +625,9 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -692,9 +636,9 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -703,17 +647,17 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData3], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); }); - it("A proposal can still be executed if a freeze proposal has been created, but threshold has not been met", async () => { + it('A proposal can still be executed if a freeze proposal has been created, but threshold has not been met', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); const proposalTransaction = { to: await childVotesERC20.getAddress(), @@ -724,9 +668,9 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction], - "" + '', ); // Proposal is active @@ -755,9 +699,7 @@ describe("Azorius Child DAO with Multisig parent", () => { // Proposal is ready to execute expect(await azoriusModule.proposalState(0)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -766,29 +708,27 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData], - [0] + [0], ); // Proposal is executed expect(await azoriusModule.proposalState(0)).to.eq(3); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(90); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(90); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(10); }); - it("A frozen DAO is automatically unfrozen after the freeze duration is over", async () => { + it('A frozen DAO is automatically unfrozen after the freeze duration is over', async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 5] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 5, + ]); const proposalTransaction1 = { to: await childVotesERC20.getAddress(), @@ -806,16 +746,16 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction2], - "" + '', ); // Proposal is active @@ -858,9 +798,9 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -869,17 +809,17 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Increase time so that freeze period has ended await time.advanceBlocks(200); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 4] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 4, + ]); const proposalTransaction3 = { to: await childVotesERC20.getAddress(), @@ -890,9 +830,9 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction3], - "" + '', ); expect(await azoriusModule.proposalState(2)).to.eq(0); @@ -912,9 +852,7 @@ describe("Azorius Child DAO with Multisig parent", () => { // Proposal is ready to execute expect(await azoriusModule.proposalState(2)).to.eq(2); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -923,34 +861,32 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData3], - [0] + [0], ); // Proposal is executed expect(await azoriusModule.proposalState(2)).to.eq(3); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(96); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(96); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(4); }); it("A frozen DAO can be unfrozen by its owner, and continue to execute TX's", async () => { // Create transaction to transfer tokens to the deployer - const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 10] - ); + const tokenTransferData1 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 10, + ]); - const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 5] - ); + const tokenTransferData2 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 5, + ]); - const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 4] - ); + const tokenTransferData3 = childVotesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 4, + ]); const proposalTransaction1 = { to: await childVotesERC20.getAddress(), @@ -975,21 +911,21 @@ describe("Azorius Child DAO with Multisig parent", () => { await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction1], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction2], - "" + '', ); await azoriusModule.submitProposal( await linearERC20Voting.getAddress(), - "0x", + '0x', [proposalTransaction3], - "" + '', ); // Proposal is active @@ -1039,9 +975,9 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -1050,9 +986,9 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData2], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // This proposal should fail due to freeze await expect( @@ -1061,9 +997,9 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData3], - [0] - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + [0], + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Parent DAO unfreezes the child await freezeVoting.connect(freezeVotingOwner).unfreeze(); @@ -1071,9 +1007,7 @@ describe("Azorius Child DAO with Multisig parent", () => { // Child DAO is now unfrozen expect(await freezeVoting.isFrozen()).to.eq(false); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(100); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(100); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(0); // Execute the transaction @@ -1082,19 +1016,17 @@ describe("Azorius Child DAO with Multisig parent", () => { [await childVotesERC20.getAddress()], [0], [tokenTransferData1], - [0] + [0], ); // Proposal is executed expect(await azoriusModule.proposalState(0)).to.eq(3); - expect( - await childVotesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(90); + expect(await childVotesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(90); expect(await childVotesERC20.balanceOf(deployer.address)).to.eq(10); }); - it("Freeze state values are updated correctly throughout the freeze process", async () => { + it('Freeze state values are updated correctly throughout the freeze process', async () => { // freeze votes threshold => 2 // freeze proposal duration in blocks => 10 // freeze duration in blocks => 200 @@ -1102,10 +1034,10 @@ describe("Azorius Child DAO with Multisig parent", () => { // One voter casts freeze vote await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); - const firstFreezeProposalCreatedBlock = - (await hre.ethers.provider.getBlock("latest"))!.number; + const firstFreezeProposalCreatedBlock = (await hre.ethers.provider.getBlock('latest'))! + .number; expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - firstFreezeProposalCreatedBlock + firstFreezeProposalCreatedBlock, ); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(1); @@ -1115,14 +1047,14 @@ describe("Azorius Child DAO with Multisig parent", () => { expect( await freezeVoting.userHasFreezeVoted( parentMultisigOwner1.address, - firstFreezeProposalCreatedBlock - ) + firstFreezeProposalCreatedBlock, + ), ).to.eq(true); expect( await freezeVoting.userHasFreezeVoted( parentMultisigOwner2.address, - firstFreezeProposalCreatedBlock - ) + firstFreezeProposalCreatedBlock, + ), ).to.eq(false); // Increase time so freeze proposal has ended @@ -1131,11 +1063,11 @@ describe("Azorius Child DAO with Multisig parent", () => { // One voter casts freeze vote, this should create a new freeze proposal await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); - const secondFreezeProposalCreatedBlock = - (await hre.ethers.provider.getBlock("latest"))!.number; + const secondFreezeProposalCreatedBlock = (await hre.ethers.provider.getBlock('latest'))! + .number; expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - secondFreezeProposalCreatedBlock + secondFreezeProposalCreatedBlock, ); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(1); @@ -1145,26 +1077,26 @@ describe("Azorius Child DAO with Multisig parent", () => { expect( await freezeVoting.userHasFreezeVoted( parentMultisigOwner1.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(true); expect( await freezeVoting.userHasFreezeVoted( parentMultisigOwner2.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(false); // First voter cannot vote again await expect( - freezeVoting.connect(parentMultisigOwner1).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "AlreadyVoted"); + freezeVoting.connect(parentMultisigOwner1).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'AlreadyVoted'); // Second voter casts freeze vote, should update state of current freeze proposal await freezeVoting.connect(parentMultisigOwner2).castFreezeVote(); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - secondFreezeProposalCreatedBlock + secondFreezeProposalCreatedBlock, ); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(2); @@ -1174,14 +1106,14 @@ describe("Azorius Child DAO with Multisig parent", () => { expect( await freezeVoting.userHasFreezeVoted( parentMultisigOwner1.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(true); expect( await freezeVoting.userHasFreezeVoted( parentMultisigOwner2.address, - secondFreezeProposalCreatedBlock - ) + secondFreezeProposalCreatedBlock, + ), ).to.eq(true); // Move time forward, freeze should still be active @@ -1193,7 +1125,7 @@ describe("Azorius Child DAO with Multisig parent", () => { await time.advanceBlocks(200); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - secondFreezeProposalCreatedBlock + secondFreezeProposalCreatedBlock, ); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(2); diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 6c308a50..d20a600c 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -1,3 +1,6 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { GnosisSafeL2, GnosisSafeL2__factory, @@ -15,24 +18,12 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, -} from "../typechain-types"; +} from '../typechain-types'; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; +import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, -} from "./GlobalSafeDeployments.test"; -import { - executeSafeTransaction, - getHatAccount, - predictGnosisSafeAddress, -} from "./helpers"; - -describe("DecentHats_0_1_0", () => { +describe('DecentHats_0_1_0', () => { let dao: SignerWithAddress; let mockHats: MockHats; @@ -65,21 +56,18 @@ describe("DecentHats_0_1_0", () => { mockHatsAddress = await mockHats.getAddress(); keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory( - deployer - ).deploy(); - mockHatsAccountImplementationAddress = - await mockHatsAccountImplementation.getAddress(); + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); decentHatsAddress = await decentHats.getAddress(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = - await gnosisSafeL2Singleton.getAddress(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); - const createGnosisSetupCalldata = - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'setup', + [ [dao.address], 1, hre.ethers.ZeroAddress, @@ -88,202 +76,182 @@ describe("DecentHats_0_1_0", () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ]); - - const saltNum = BigInt( - `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` + ], ); + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); gnosisSafeAddress = predictedGnosisSafeAddress; await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, - saltNum + saltNum, ); - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory( - deployer - ).deploy(); + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); mockSablierAddress = await mockSablier.getAddress(); - mockERC20 = await new MockERC20__factory(deployer).deploy( - "MockERC20", - "MCK" - ); + mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); mockERC20Address = await mockERC20.getAddress(); - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); }); - describe("DecentHats", () => { + describe('DecentHats', () => { let enableModuleTx: ethers.ContractTransactionResponse; beforeEach(async () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: - GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentHatsAddress] - ), + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'enableModule', + [decentHatsAddress], + ), signers: [dao], }); }); - describe("Enabled as a module", () => { - it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); + describe('Enabled as a module', () => { + it('Emits an ExecutionSuccess event', async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an EnabledModule event", async () => { + it('Emits an EnabledModule event', async () => { await expect(enableModuleTx) - .to.emit(gnosisSafe, "EnabledModule") + .to.emit(gnosisSafe, 'EnabledModule') .withArgs(decentHatsAddress); }); }); - describe("Creating a new Top Hat and Tree", () => { + describe('Creating a new Top Hat and Tree', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; beforeEach(async () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ] - ), + { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + ], + }, + ], + ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentHatsAddress); }); - it("Emits some hatsTreeId ValueUpdated events", async () => { + it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) - .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0"); + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '0'); }); - describe("Multiple calls", () => { + describe('Multiple calls', () => { let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; beforeEach(async () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], }, - ] - ), + hats: [], + }, + ], + ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx2).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx2) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentHatsAddress); }); - it("Creates Top Hats with sequential IDs", async () => { + it('Creates Top Hats with sequential IDs', async () => { await expect(createAndDeclareTreeTx2) - .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "4"); + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '4'); }); }); - describe("Creating Hats Accounts", () => { - it("Generates the correct Addresses for the current Hats", async () => { + describe('Creating Hats Accounts', () => { + it('Generates the correct Addresses for the current Hats', async () => { const currentCount = await mockHats.count(); for (let i = 0n; i < currentCount; i++) { @@ -291,130 +259,122 @@ describe("DecentHats_0_1_0", () => { i, erc6551Registry, mockHatsAccountImplementationAddress, - mockHatsAddress + mockHatsAddress, ); expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq( - mockHatsAddress - ); + expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); } }); }); }); - describe("Creating a new Top Hat and Tree with Sablier Streams", () => { + describe('Creating a new Top Hat and Tree with Sablier Streams', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + { + maxSupply: 1, + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ] - ), + ], + }, + ], + ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit( - gnosisSafe, - "ExecutionSuccess" - ); + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentHatsAddress); }); - it("Emits some hatsTreeId ValueUpdated events", async () => { + it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) - .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0"); + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '0'); }); - it("Creates a Sablier stream for the hat with stream parameters", async () => { + it('Creates a Sablier stream for the hat with stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(1); const event = streamCreatedEvents[0]; expect(event.args.sender).to.equal(gnosisSafeAddress); expect(event.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event.args.totalAmount).to.equal(ethers.parseEther("100")); + expect(event.args.totalAmount).to.equal(ethers.parseEther('100')); }); - it("Does not create a Sablier stream for hats without stream parameters", async () => { + it('Does not create a Sablier stream for hats without stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created }); - it("Creates a Sablier stream with correct timestamps", async () => { + it('Creates a Sablier stream with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(1); @@ -426,133 +386,122 @@ describe("DecentHats_0_1_0", () => { }); }); - describe("Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat", () => { + describe('Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat', () => { let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: - mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now }, - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("50"), - asset: mockERC20Address, - cancelable: false, - transferable: true, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, // No cliff - end: currentBlockTimestamp + 1296000, // 15 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('50'), + asset: mockERC20Address, + cancelable: false, + transferable: true, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, // No cliff + end: currentBlockTimestamp + 1296000, // 15 days from now }, - ], - }, - ], - }, - ] - ), + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + ], + }, + ], + ), signers: [dao], }); }); - it("Creates multiple Sablier streams for a single hat", async () => { + it('Creates multiple Sablier streams for a single hat', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(2); const event1 = streamCreatedEvents[0]; expect(event1.args.sender).to.equal(gnosisSafeAddress); expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")); + expect(event1.args.totalAmount).to.equal(ethers.parseEther('100')); const event2 = streamCreatedEvents[1]; expect(event2.args.sender).to.equal(gnosisSafeAddress); expect(event2.args.recipient).to.equal(event1.args.recipient); - expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")); + expect(event2.args.totalAmount).to.equal(ethers.parseEther('50')); }); - it("Creates streams with correct parameters", async () => { + it('Creates streams with correct parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); - expect(stream1.cancelable).to.be.true; - expect(stream1.transferable).to.be.false; + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); + expect(stream1.cancelable === true); + expect(stream1.transferable === false); expect(stream1.endTime - stream1.startTime).to.equal(2592000); - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); - expect(stream2.cancelable).to.be.false; - expect(stream2.transferable).to.be.true; + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); + expect(stream2.cancelable === false); + expect(stream2.transferable === true); expect(stream2.endTime - stream2.startTime).to.equal(1296000); }); - it("Creates streams with correct timestamps", async () => { + it('Creates streams with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); - const stream1 = await mockSablier.getStream( - streamCreatedEvents[0].args.streamId - ); + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); expect(stream1.startTime).to.equal(currentBlockTimestamp); expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); - const stream2 = await mockSablier.getStream( - streamCreatedEvents[1].args.streamId - ); + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); expect(stream2.startTime).to.equal(currentBlockTimestamp); expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); }); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 227477c4..de11ac61 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -1,3 +1,6 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { DecentHats_0_1_0, DecentHats_0_1_0__factory, @@ -16,25 +19,12 @@ import { MockHatsAccount__factory, MockSablierV2LockupLinear, MockSablierV2LockupLinear__factory, -} from "../typechain-types"; +} from '../typechain-types'; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; +import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from './GlobalSafeDeployments.test'; +import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; -import { - executeSafeTransaction, - getHatAccount, - predictGnosisSafeAddress, -} from "./helpers"; - -import { - getGnosisSafeProxyFactory, - getGnosisSafeL2Singleton, -} from "./GlobalSafeDeployments.test"; - -describe("DecentSablierStreamManagement", () => { +describe('DecentSablierStreamManagement', () => { let dao: SignerWithAddress; let gnosisSafe: GnosisSafeL2; @@ -66,34 +56,29 @@ describe("DecentSablierStreamManagement", () => { let enableModuleTx: ethers.ContractTransactionResponse; let createAndDeclareTreeWithRolesAndStreamsTx: ethers.ContractTransactionResponse; - const streamFundsMax = ethers.parseEther("100"); + const streamFundsMax = ethers.parseEther('100'); beforeEach(async () => { const signers = await hre.ethers.getSigners(); const [deployer] = signers; [, dao] = signers; - decentSablierManagement = await new DecentSablierStreamManagement__factory( - deployer - ).deploy(); + decentSablierManagement = await new DecentSablierStreamManagement__factory(deployer).deploy(); decentSablierManagementAddress = await decentSablierManagement.getAddress(); - mockHatsAccountImplementation = await new MockHatsAccount__factory( - deployer - ).deploy(); - mockHatsAccountImplementationAddress = - await mockHatsAccountImplementation.getAddress(); + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); decentHatsAddress = await decentHats.getAddress(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = - await gnosisSafeL2Singleton.getAddress(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); - const createGnosisSetupCalldata = - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'setup', + [ [dao.address], 1, hre.ethers.ZeroAddress, @@ -102,59 +87,47 @@ describe("DecentSablierStreamManagement", () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ]); - - const saltNum = BigInt( - `0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}` + ], ); + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); gnosisSafeAddress = predictedGnosisSafeAddress; await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, - saltNum + saltNum, ); - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory( - deployer - ).deploy(); + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); mockSablierAddress = await mockSablier.getAddress(); - mockERC20 = await new MockERC20__factory(deployer).deploy( - "MockERC20", - "MCK" - ); + mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); mockERC20Address = await mockERC20.getAddress(); - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")); + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); // Set up the Safe with roles and streams await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: - GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentHatsAddress] - ), + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData('enableModule', [ + decentHatsAddress, + ]), signers: [dao], }); - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))! - .timestamp; + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; mockHats = await new MockHats__factory(deployer).deploy(); mockHatsAddress = await mockHats.getAddress(); @@ -164,68 +137,62 @@ describe("DecentSablierStreamManagement", () => { createAndDeclareTreeWithRolesAndStreamsTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: - DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", - adminHat: { + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: "", - imageURI: "", - isMutable: false, - wearer: dao.address, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: streamFundsMax, - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, + wearer: dao.address, + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: streamFundsMax, + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days from now }, - ], - }, - ], - }, - ] - ), + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + ], + }, + ], + ), signers: [dao], }); + await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit(gnosisSafe, 'ExecutionSuccess'); await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit( gnosisSafe, - "ExecutionSuccess" - ); - await expect(createAndDeclareTreeWithRolesAndStreamsTx).to.emit( - gnosisSafe, - "ExecutionFromModuleSuccess" + 'ExecutionFromModuleSuccess', ); - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ); + const streamCreatedEvents = await mockSablier.queryFilter(mockSablier.filters.StreamCreated()); expect(streamCreatedEvents.length).to.equal(1); streamId = streamCreatedEvents[0].args.streamId; @@ -234,49 +201,45 @@ describe("DecentSablierStreamManagement", () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, - transactionData: - GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentSablierManagementAddress] - ), + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData('enableModule', [ + decentSablierManagementAddress, + ]), signers: [dao], }); }); - describe("Enabled as a Module", () => { - it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess"); + describe('Enabled as a Module', () => { + it('Emits an ExecutionSuccess event', async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an EnabledModule event", async () => { + it('Emits an EnabledModule event', async () => { await expect(enableModuleTx) - .to.emit(gnosisSafe, "EnabledModule") + .to.emit(gnosisSafe, 'EnabledModule') .withArgs(decentSablierManagementAddress); }); }); - describe("Withdrawing From Stream", () => { + describe('Withdrawing From Stream', () => { let withdrawTx: ethers.ContractTransactionResponse; - describe("When the stream has funds", () => { + describe('When the stream has funds', () => { beforeEach(async () => { // Advance time to the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [ currentBlockTimestamp + 2592000, ]); - await hre.ethers.provider.send("evm_mine", []); + await hre.ethers.provider.send('evm_mine', []); // No action has been taken yet on the stream. Balance should be untouched. - expect(await mockSablier.withdrawableAmountOf(streamId)).to.eq( - streamFundsMax - ); + expect(await mockSablier.withdrawableAmountOf(streamId)).to.eq(streamFundsMax); const recipientHatAccount = await getHatAccount( 2n, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, - dao + dao, ); withdrawTx = await executeSafeTransaction({ @@ -284,60 +247,55 @@ describe("DecentSablierStreamManagement", () => { to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "withdrawMaxFromStream", - [ - mockSablierAddress, - await recipientHatAccount.getAddress(), - streamId, - dao.address, - ] + 'withdrawMaxFromStream', + [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address], ), signers: [dao], }); - expect(withdrawTx).to.not.reverted; + await expect(withdrawTx).to.not.be.reverted; }); - it("Emits an ExecutionSuccess event", async () => { - await expect(withdrawTx).to.emit(gnosisSafe, "ExecutionSuccess"); + it('Emits an ExecutionSuccess event', async () => { + await expect(withdrawTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(withdrawTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentSablierManagementAddress); }); - it("Withdraws the maximum amount from the stream", async () => { + it('Withdraws the maximum amount from the stream', async () => { expect(await mockSablier.withdrawableAmountOf(streamId)).to.equal(0); }); }); - describe("When the stream has no funds", () => { + describe('When the stream has no funds', () => { beforeEach(async () => { // Advance time to the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [ currentBlockTimestamp + 2592000, ]); - await hre.ethers.provider.send("evm_mine", []); + await hre.ethers.provider.send('evm_mine', []); const recipientHatAccount = await getHatAccount( 2n, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, - dao + dao, ); // The recipient withdraws the full amount await recipientHatAccount.execute( mockSablierAddress, 0n, - MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData( - "withdrawMax", - [streamId, dao.address] - ), - 0 + MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData('withdrawMax', [ + streamId, + dao.address, + ]), + 0, ); expect(await mockSablier.withdrawableAmountOf(streamId)).to.equal(0); @@ -347,116 +305,105 @@ describe("DecentSablierStreamManagement", () => { to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "withdrawMaxFromStream", - [ - mockSablierAddress, - await recipientHatAccount.getAddress(), - streamId, - dao.address, - ] + 'withdrawMaxFromStream', + [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address], ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(withdrawTx).to.emit(gnosisSafe, "ExecutionSuccess"); + it('Emits an ExecutionSuccess event', async () => { + await expect(withdrawTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Does not emit an ExecutionFromModuleSuccess event", async () => { - await expect(withdrawTx).to.not.emit( - gnosisSafe, - "ExecutionFromModuleSuccess" - ); + it('Does not emit an ExecutionFromModuleSuccess event', async () => { + await expect(withdrawTx).to.not.emit(gnosisSafe, 'ExecutionFromModuleSuccess'); }); - it("Does not revert", async () => { - expect(withdrawTx).to.not.reverted; + it('Does not revert', async () => { + await expect(withdrawTx).to.not.be.reverted; }); }); }); - describe("Cancelling From Stream", () => { + describe('Cancelling From Stream', () => { let cancelTx: ethers.ContractTransactionResponse; - describe("When the stream is active", () => { + describe('When the stream is active', () => { beforeEach(async () => { // Advance time to before the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [ currentBlockTimestamp + 60000, ]); // 1 minute from now - await hre.ethers.provider.send("evm_mine", []); + await hre.ethers.provider.send('evm_mine', []); cancelTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "cancelStream", - [mockSablierAddress, streamId] + 'cancelStream', + [mockSablierAddress, streamId], ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(cancelTx).to.emit(gnosisSafe, "ExecutionSuccess"); + it('Emits an ExecutionSuccess event', async () => { + await expect(cancelTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(cancelTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentSablierManagementAddress); }); - it("Cancels the stream", async () => { + it('Cancels the stream', async () => { expect(await mockSablier.statusOf(streamId)).to.equal(3); // 3 === LockupLinear.Status.CANCELED }); }); - describe("When the stream has expired", () => { + describe('When the stream has expired', () => { beforeEach(async () => { // Advance time to the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [ currentBlockTimestamp + 2592000 + 60000, ]); // 30 days from now + 1 minute - await hre.ethers.provider.send("evm_mine", []); + await hre.ethers.provider.send('evm_mine', []); cancelTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "cancelStream", - [mockSablierAddress, streamId] + 'cancelStream', + [mockSablierAddress, streamId], ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(cancelTx).to.emit(gnosisSafe, "ExecutionSuccess"); + it('Emits an ExecutionSuccess event', async () => { + await expect(cancelTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Does not emit an ExecutionFromModuleSuccess event", async () => { - await expect(cancelTx).to.not.emit( - gnosisSafe, - "ExecutionFromModuleSuccess" - ); + it('Does not emit an ExecutionFromModuleSuccess event', async () => { + await expect(cancelTx).to.not.emit(gnosisSafe, 'ExecutionFromModuleSuccess'); }); - it("Does not revert", async () => { - expect(cancelTx).to.not.reverted; + it('Does not revert', async () => { + await expect(cancelTx).to.not.be.reverted; }); }); - describe("When the stream has been previously cancelled", () => { + describe('When the stream has been previously cancelled', () => { beforeEach(async () => { // Advance time to before the end of the stream - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [ currentBlockTimestamp + 120000, ]); // 2 minutes from now - await hre.ethers.provider.send("evm_mine", []); + await hre.ethers.provider.send('evm_mine', []); const stream = await mockSablier.getStream(streamId); expect(stream.endTime).to.be.greaterThan(currentBlockTimestamp); @@ -465,44 +412,40 @@ describe("DecentSablierStreamManagement", () => { await executeSafeTransaction({ safe: gnosisSafe, to: mockSablierAddress, - transactionData: - MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData( - "cancel", - [streamId] - ), + transactionData: MockSablierV2LockupLinear__factory.createInterface().encodeFunctionData( + 'cancel', + [streamId], + ), signers: [dao], }); - await hre.ethers.provider.send("evm_setNextBlockTimestamp", [ + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [ currentBlockTimestamp + 240000, ]); // 4 minutes from now - await hre.ethers.provider.send("evm_mine", []); + await hre.ethers.provider.send('evm_mine', []); cancelTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( - "cancelStream", - [mockSablierAddress, streamId] + 'cancelStream', + [mockSablierAddress, streamId], ), signers: [dao], }); }); - it("Emits an ExecutionSuccess event", async () => { - await expect(cancelTx).to.emit(gnosisSafe, "ExecutionSuccess"); + it('Emits an ExecutionSuccess event', async () => { + await expect(cancelTx).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Does not emit an ExecutionFromModuleSuccess event", async () => { - await expect(cancelTx).to.not.emit( - gnosisSafe, - "ExecutionFromModuleSuccess" - ); + it('Does not emit an ExecutionFromModuleSuccess event', async () => { + await expect(cancelTx).to.not.emit(gnosisSafe, 'ExecutionFromModuleSuccess'); }); - it("Does not revert", async () => { - expect(cancelTx).to.not.reverted; + it('Does not revert', async () => { + await expect(cancelTx).to.not.be.reverted; }); }); }); diff --git a/test/ERC20-Claim.test.ts b/test/ERC20-Claim.test.ts index 4def7119..798f5618 100644 --- a/test/ERC20-Claim.test.ts +++ b/test/ERC20-Claim.test.ts @@ -1,21 +1,20 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import chai from 'chai'; +import hre, { ethers } from 'hardhat'; import { VotesERC20, VotesERC20__factory, ERC20Claim, ERC20Claim__factory, ModuleProxyFactory, -} from "../typechain-types"; -import chai from "chai"; -import hre from "hardhat"; -import { ethers } from "ethers"; -import time from "./time"; -import { calculateProxyAddress } from "./helpers"; -import { getModuleProxyFactory } from "./GlobalSafeDeployments.test"; +} from '../typechain-types'; +import { getModuleProxyFactory } from './GlobalSafeDeployments.test'; +import { calculateProxyAddress } from './helpers'; +import time from './time'; const expect = chai.expect; -describe("ERC-20 Token Claiming", function () { +describe('ERC-20 Token Claiming', function () { let moduleProxyFactory: ModuleProxyFactory; let votesERC20Mastercopy: VotesERC20; let parentERC20: VotesERC20; @@ -39,82 +38,76 @@ describe("ERC-20 Token Claiming", function () { const parentERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "ParentDecent", - "pDCNT", + 'ParentDecent', + 'pDCNT', [deployer.address, userA.address], - [ethers.parseUnits("100", 18), ethers.parseUnits("150", 18)], - ] + [ethers.parseUnits('100', 18), ethers.parseUnits('150', 18)], + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), parentERC20SetupData, - "10031021" + '10031021', ); const predictedParentVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), parentERC20SetupData, - "10031021" + '10031021', ); - parentERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedParentVotesERC20Address - ); + parentERC20 = await hre.ethers.getContractAt('VotesERC20', predictedParentVotesERC20Address); const childERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "ChildDecent", - "cDCNT", + 'ChildDecent', + 'cDCNT', [userB.address, deployer.address], - [ethers.parseUnits("100", 18), ethers.parseUnits("100", 18)], - ] + [ethers.parseUnits('100', 18), ethers.parseUnits('100', 18)], + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), childERC20SetupData, - "10031021" + '10031021', ); const predictedChildVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), childERC20SetupData, - "10031021" + '10031021', ); - childERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedChildVotesERC20Address - ); + childERC20 = await hre.ethers.getContractAt('VotesERC20', predictedChildVotesERC20Address); - const latestBlock = await hre.ethers.provider.getBlock("latest"); + const latestBlock = await hre.ethers.provider.getBlock('latest'); const erc20ClaimSetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["uint32", "address", "address", "address", "uint256"], + ['uint32', 'address', 'address', 'address', 'uint256'], [ latestBlock!.number + 5, deployer.address, await parentERC20.getAddress(), await childERC20.getAddress(), - ethers.parseUnits("100", 18), - ] + ethers.parseUnits('100', 18), + ], ), ]); @@ -122,165 +115,147 @@ describe("ERC-20 Token Claiming", function () { moduleProxyFactory, await erc20ClaimMastercopy.getAddress(), erc20ClaimSetupData, - "10031021" + '10031021', ); await childERC20 .connect(deployer) - .approve(predictedERC20ClaimAddress, ethers.parseUnits("100", 18)); + .approve(predictedERC20ClaimAddress, ethers.parseUnits('100', 18)); await moduleProxyFactory.deployModule( await erc20ClaimMastercopy.getAddress(), erc20ClaimSetupData, - "10031021" + '10031021', ); - erc20Claim = await hre.ethers.getContractAt( - "ERC20Claim", - predictedERC20ClaimAddress - ); + erc20Claim = await hre.ethers.getContractAt('ERC20Claim', predictedERC20ClaimAddress); }); - it("Init is correct", async () => { - expect(await parentERC20.name()).to.eq("ParentDecent"); - expect(await parentERC20.symbol()).to.eq("pDCNT"); - expect(await parentERC20.totalSupply()).to.eq(ethers.parseUnits("250", 18)); - expect(await parentERC20.balanceOf(deployer.address)).to.eq( - ethers.parseUnits("100", 18) - ); - expect(await parentERC20.balanceOf(userA.address)).to.eq( - ethers.parseUnits("150", 18) - ); - - expect(await childERC20.name()).to.eq("ChildDecent"); - expect(await childERC20.symbol()).to.eq("cDCNT"); - expect(await childERC20.totalSupply()).to.eq(ethers.parseUnits("200", 18)); - expect(await childERC20.balanceOf(userB.address)).to.eq( - ethers.parseUnits("100", 18) - ); - expect(await childERC20.balanceOf(deployer.address)).to.eq( - ethers.parseUnits("0", 18) - ); + it('Init is correct', async () => { + expect(await parentERC20.name()).to.eq('ParentDecent'); + expect(await parentERC20.symbol()).to.eq('pDCNT'); + expect(await parentERC20.totalSupply()).to.eq(ethers.parseUnits('250', 18)); + expect(await parentERC20.balanceOf(deployer.address)).to.eq(ethers.parseUnits('100', 18)); + expect(await parentERC20.balanceOf(userA.address)).to.eq(ethers.parseUnits('150', 18)); + + expect(await childERC20.name()).to.eq('ChildDecent'); + expect(await childERC20.symbol()).to.eq('cDCNT'); + expect(await childERC20.totalSupply()).to.eq(ethers.parseUnits('200', 18)); + expect(await childERC20.balanceOf(userB.address)).to.eq(ethers.parseUnits('100', 18)); + expect(await childERC20.balanceOf(deployer.address)).to.eq(ethers.parseUnits('0', 18)); expect(await childERC20.balanceOf(await erc20Claim.getAddress())).to.eq( - ethers.parseUnits("100", 18) + ethers.parseUnits('100', 18), ); }); - it("Inits ClaimSubsidiary contract", async () => { + it('Inits ClaimSubsidiary contract', async () => { expect(await erc20Claim.childERC20()).to.eq(await childERC20.getAddress()); - expect(await erc20Claim.parentERC20()).to.eq( - await parentERC20.getAddress() - ); + expect(await erc20Claim.parentERC20()).to.eq(await parentERC20.getAddress()); expect(await erc20Claim.snapShotId()).to.eq(1); - expect(await erc20Claim.parentAllocation()).to.eq( - ethers.parseUnits("100", 18) - ); + expect(await erc20Claim.parentAllocation()).to.eq(ethers.parseUnits('100', 18)); }); - it("Claim Snap", async () => { + it('Claim Snap', async () => { const amount = await erc20Claim.getClaimAmount(deployer.address); // Claim on behalf - await expect( - erc20Claim.connect(userB).claimTokens(deployer.address) - ).to.emit(erc20Claim, "ERC20Claimed"); + await expect(erc20Claim.connect(userB).claimTokens(deployer.address)).to.emit( + erc20Claim, + 'ERC20Claimed', + ); expect( amount + (await erc20Claim.getClaimAmount(userA.address)) + - (await erc20Claim.getClaimAmount(await erc20Claim.getAddress())) - ).to.eq(ethers.parseUnits("100", 18)); + (await erc20Claim.getClaimAmount(await erc20Claim.getAddress())), + ).to.eq(ethers.parseUnits('100', 18)); expect(await childERC20.balanceOf(deployer.address)).to.eq(amount); expect(await childERC20.balanceOf(await erc20Claim.getAddress())).to.eq( - ethers.parseUnits("100", 18) - amount + ethers.parseUnits('100', 18) - amount, ); }); - it("Should revert double claim", async () => { - await expect(erc20Claim.claimTokens(deployer.address)).to.emit( - erc20Claim, - "ERC20Claimed" - ); + it('Should revert double claim', async () => { + await expect(erc20Claim.claimTokens(deployer.address)).to.emit(erc20Claim, 'ERC20Claimed'); expect(await erc20Claim.getClaimAmount(deployer.address)).to.eq(0); await expect( - erc20Claim.connect(userA).claimTokens(deployer.address) - ).to.revertedWithCustomError(erc20Claim, "NoAllocation"); - await expect( - erc20Claim.claimTokens(deployer.address) - ).to.revertedWithCustomError(erc20Claim, "NoAllocation"); + erc20Claim.connect(userA).claimTokens(deployer.address), + ).to.revertedWithCustomError(erc20Claim, 'NoAllocation'); + await expect(erc20Claim.claimTokens(deployer.address)).to.revertedWithCustomError( + erc20Claim, + 'NoAllocation', + ); }); - it("Should revert without an allocation", async () => { - await expect( - erc20Claim.claimTokens(userB.address) - ).to.revertedWithCustomError(erc20Claim, "NoAllocation"); + it('Should revert without an allocation', async () => { + await expect(erc20Claim.claimTokens(userB.address)).to.revertedWithCustomError( + erc20Claim, + 'NoAllocation', + ); }); - it("Should revert a non funder reclaim", async () => { - await expect( - erc20Claim.connect(userA).reclaim() - ).to.revertedWithCustomError(erc20Claim, "NotTheFunder"); + it('Should revert a non funder reclaim', async () => { + await expect(erc20Claim.connect(userA).reclaim()).to.revertedWithCustomError( + erc20Claim, + 'NotTheFunder', + ); }); - it("Should revert an unexpired reclaim", async () => { - await expect( - erc20Claim.connect(deployer).reclaim() - ).to.revertedWithCustomError(erc20Claim, "DeadlinePending"); + it('Should revert an unexpired reclaim', async () => { + await expect(erc20Claim.connect(deployer).reclaim()).to.revertedWithCustomError( + erc20Claim, + 'DeadlinePending', + ); }); - it("Should allow an expired reclaim", async () => { + it('Should allow an expired reclaim', async () => { await time.advanceBlocks(5); await erc20Claim.connect(deployer).reclaim(); - expect(await childERC20.balanceOf(deployer.address)).to.eq( - ethers.parseUnits("100", 18) - ); + expect(await childERC20.balanceOf(deployer.address)).to.eq(ethers.parseUnits('100', 18)); }); - it("If the deadlineBlock is setup as zero, then calling reclaim will revert", async () => { + it('If the deadlineBlock is setup as zero, then calling reclaim will revert', async () => { const abiCoder2 = new ethers.AbiCoder(); const childERC20SetupData2 = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder2.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "ChildDecent", - "cDCNT", + 'ChildDecent', + 'cDCNT', [userB.address, deployer.address], - [ethers.parseUnits("200", 18), ethers.parseUnits("200", 18)], - ] + [ethers.parseUnits('200', 18), ethers.parseUnits('200', 18)], + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), childERC20SetupData2, - "10031021" + '10031021', ); const predictedChildVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), childERC20SetupData2, - "10031021" + '10031021', ); - childERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedChildVotesERC20Address - ); + childERC20 = await hre.ethers.getContractAt('VotesERC20', predictedChildVotesERC20Address); const erc20ClaimSetupData2 = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder2.encode( - ["uint32", "address", "address", "address", "uint256"], + ['uint32', 'address', 'address', 'address', 'uint256'], [ 0, deployer.address, await parentERC20.getAddress(), await childERC20.getAddress(), - ethers.parseUnits("100", 18), - ] + ethers.parseUnits('100', 18), + ], ), ]); @@ -288,26 +263,24 @@ describe("ERC-20 Token Claiming", function () { moduleProxyFactory, await erc20ClaimMastercopy.getAddress(), erc20ClaimSetupData2, - "10031021" + '10031021', ); await childERC20 .connect(deployer) - .approve(predictedERC20ClaimAddress, ethers.parseUnits("100", 18)); + .approve(predictedERC20ClaimAddress, ethers.parseUnits('100', 18)); await moduleProxyFactory.deployModule( await erc20ClaimMastercopy.getAddress(), erc20ClaimSetupData2, - "10031021" + '10031021', ); - erc20Claim = await hre.ethers.getContractAt( - "ERC20Claim", - predictedERC20ClaimAddress - ); + erc20Claim = await hre.ethers.getContractAt('ERC20Claim', predictedERC20ClaimAddress); - await expect( - erc20Claim.connect(deployer).reclaim() - ).to.be.revertedWithCustomError(erc20Claim, "NoDeadline"); + await expect(erc20Claim.connect(deployer).reclaim()).to.be.revertedWithCustomError( + erc20Claim, + 'NoDeadline', + ); }); }); diff --git a/test/Fractal-Module.test.ts b/test/Fractal-Module.test.ts index bf37b15b..75de7dea 100644 --- a/test/Fractal-Module.test.ts +++ b/test/Fractal-Module.test.ts @@ -1,7 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import { ethers } from "ethers"; -import hre from "hardhat"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { VotesERC20__factory, FractalModule, @@ -14,22 +13,22 @@ import { GnosisSafeL2__factory, MultiSendCallOnly__factory, MultiSendCallOnly, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, + getMultiSendCallOnly, +} from './GlobalSafeDeployments.test'; import { calculateProxyAddress, predictGnosisSafeAddress, buildContractCall, MetaTransaction, encodeMultiSend, -} from "./helpers"; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, - getMultiSendCallOnly, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; -describe("Fractal Module Tests", () => { +describe('Fractal Module Tests', () => { let gnosisSafeProxyFactory: GnosisSafeProxyFactory; let moduleProxyFactory: ModuleProxyFactory; let gnosisSafeL2Singleton: GnosisSafeL2; @@ -52,9 +51,7 @@ describe("Fractal Module Tests", () => { let freezeGuardSetup: string; let setModuleCalldata: string; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { [deployer, owner1, owner2, owner3] = await hre.ethers.getSigners(); @@ -68,13 +65,8 @@ describe("Fractal Module Tests", () => { // SETUP GnosisSafe createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [ - owner1.address, - owner2.address, - owner3.address, - await multiSendCallOnly.getAddress(), - ], + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ + [owner1.address, owner2.address, owner3.address, await multiSendCallOnly.getAddress()], 1, ethers.ZeroAddress, ethers.ZeroHash, @@ -87,36 +79,24 @@ describe("Fractal Module Tests", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Get Gnosis Safe contract // eslint-disable-next-line camelcase - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); /// ///////////// GUARD /////////////////// // DEPLOY GUARD freezeGuard = await new MultisigFreezeGuard__factory(deployer).deploy(); freezeGuardSetup = // eslint-disable-next-line camelcase - MultisigFreezeGuard__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["uint256", "uint256", "address", "address", "address"], - [ - 10, - 10, - owner1.address, - owner1.address, - await gnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeGuard__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['uint256', 'uint256', 'address', 'address', 'address'], + [10, 10, owner1.address, owner1.address, await gnosisSafe.getAddress()], + ), + ]); /// /////////////// MODULE //////////////// // DEPLOY Fractal Module @@ -125,15 +105,15 @@ describe("Fractal Module Tests", () => { // SETUP Module setModuleCalldata = // eslint-disable-next-line camelcase - FractalModule__factory.createInterface().encodeFunctionData("setUp", [ + FractalModule__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]"], + ['address', 'address', 'address', 'address[]'], [ owner1.address, await gnosisSafe.getAddress(), await gnosisSafe.getAddress(), [owner2.address], - ] + ], ), ]); @@ -141,239 +121,208 @@ describe("Fractal Module Tests", () => { moduleProxyFactory, await moduleImpl.getAddress(), setModuleCalldata, - "10031021" + '10031021', ); - fractalModule = await hre.ethers.getContractAt( - "FractalModule", - predictedFractalModule - ); + fractalModule = await hre.ethers.getContractAt('FractalModule', predictedFractalModule); }); - describe("Fractal Module", () => { - it("Supports the expected ERC165 interface", async () => { + describe('Fractal Module', () => { + it('Supports the expected ERC165 interface', async () => { const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [await moduleImpl.getAddress(), setModuleCalldata, "10031021"], + 'deployModule', + [await moduleImpl.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await expect(multiSendCallOnly.multiSend(safeTx)) - .to.emit(gnosisSafeProxyFactory, "ProxyCreation") - .withArgs( - await gnosisSafe.getAddress(), - await gnosisSafeL2Singleton.getAddress() - ); + .to.emit(gnosisSafeProxyFactory, 'ProxyCreation') + .withArgs(await gnosisSafe.getAddress(), await gnosisSafeL2Singleton.getAddress()); }); - it("Owner may add/remove controllers", async () => { + it('Owner may add/remove controllers', async () => { const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [await moduleImpl.getAddress(), setModuleCalldata, "10031021"], + 'deployModule', + [await moduleImpl.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await multiSendCallOnly.multiSend(safeTx); // ADD Controller - await expect( - fractalModule.connect(owner3).addControllers([owner3.address]) - ).to.revertedWith("Ownable: caller is not the owner"); + await expect(fractalModule.connect(owner3).addControllers([owner3.address])).to.revertedWith( + 'Ownable: caller is not the owner', + ); expect(await fractalModule.controllers(owner3.address)).eq(false); - await expect( - fractalModule.connect(owner1).addControllers([owner3.address]) - ).to.emit(fractalModule, "ControllersAdded"); + await expect(fractalModule.connect(owner1).addControllers([owner3.address])).to.emit( + fractalModule, + 'ControllersAdded', + ); expect(await fractalModule.controllers(owner3.address)).eq(true); // REMOVE Controller await expect( - fractalModule.connect(owner3).removeControllers([owner3.address]) - ).to.revertedWith("Ownable: caller is not the owner"); + fractalModule.connect(owner3).removeControllers([owner3.address]), + ).to.revertedWith('Ownable: caller is not the owner'); expect(await fractalModule.controllers(owner3.address)).eq(true); - await expect( - fractalModule.connect(owner1).removeControllers([owner3.address]) - ).to.emit(fractalModule, "ControllersRemoved"); + await expect(fractalModule.connect(owner1).removeControllers([owner3.address])).to.emit( + fractalModule, + 'ControllersRemoved', + ); expect(await fractalModule.controllers(owner3.address)).eq(false); }); - it("Authorized users may exec TXs", async () => { + it('Authorized users may exec TXs', async () => { const internalTxs: MetaTransaction[] = [ await buildContractCall( gnosisSafe, - "enableModule", + 'enableModule', [await fractalModule.getAddress()], 0, - false + false, ), ]; const safeInternalTx = encodeMultiSend(internalTxs); const sigs = - "0x000000000000000000000000" + + '0x000000000000000000000000' + (await multiSendCallOnly.getAddress()).slice(2) + - "0000000000000000000000000000000000000000000000000000000000000000" + - "01"; + '0000000000000000000000000000000000000000000000000000000000000000' + + '01'; const txs: MetaTransaction[] = [ await buildContractCall( gnosisSafeProxyFactory, - "createProxyWithNonce", - [ - await gnosisSafeL2Singleton.getAddress(), - createGnosisSetupCalldata, - saltNum, - ], + 'createProxyWithNonce', + [await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, saltNum], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [await moduleImpl.getAddress(), setModuleCalldata, "10031021"], + 'deployModule', + [await moduleImpl.getAddress(), setModuleCalldata, '10031021'], 0, - false + false, ), await buildContractCall( moduleProxyFactory, - "deployModule", - [await freezeGuard.getAddress(), freezeGuardSetup, "10031021"], + 'deployModule', + [await freezeGuard.getAddress(), freezeGuardSetup, '10031021'], 0, - false + false, ), await buildContractCall( gnosisSafe, - "execTransaction", + 'execTransaction', [ await multiSendCallOnly.getAddress(), // to - "0", // value + '0', // value // eslint-disable-next-line camelcase - MultiSendCallOnly__factory.createInterface().encodeFunctionData( - "multiSend", - [safeInternalTx] - ), // calldata - "1", // operation - "0", // tx gas - "0", // base gas - "0", // gas price + MultiSendCallOnly__factory.createInterface().encodeFunctionData('multiSend', [ + safeInternalTx, + ]), // calldata + '1', // operation + '0', // tx gas + '0', // base gas + '0', // gas price ethers.ZeroAddress, // gas token ethers.ZeroAddress, // receiver sigs, // sigs ], 0, - false + false, ), ]; const safeTx = encodeMultiSend(txs); await multiSendCallOnly.multiSend(safeTx); - // FUND SAFE - const abiCoder = new ethers.AbiCoder(); // encode data - // Deploy token mastercopy - const votesERC20Mastercopy = await new VotesERC20__factory( - deployer - ).deploy(); + const votesERC20Mastercopy = await new VotesERC20__factory(deployer).deploy(); const votesERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], - ["DCNT", "DCNT", [await gnosisSafe.getAddress()], [1000]] + ['string', 'string', 'address[]', 'uint256[]'], + ['DCNT', 'DCNT', [await gnosisSafe.getAddress()], [1000]], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), votesERC20SetupData, - "10031021" + '10031021', ); const predictedVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), votesERC20SetupData, - "10031021" + '10031021', ); - const votesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedVotesERC20Address - ); + const votesERC20 = await hre.ethers.getContractAt('VotesERC20', predictedVotesERC20Address); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 1000 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(1000); expect(await votesERC20.balanceOf(owner1.address)).to.eq(0); // CLAWBACK FUNDS const clawBackCalldata = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("transfer", [ - owner1.address, - 500, - ]); + VotesERC20__factory.createInterface().encodeFunctionData('transfer', [owner1.address, 500]); const txData = // eslint-disable-next-line camelcase abiCoder.encode( - ["address", "uint256", "bytes", "uint8"], - [await votesERC20.getAddress(), 0, clawBackCalldata, 0] + ['address', 'uint256', 'bytes', 'uint8'], + [await votesERC20.getAddress(), 0, clawBackCalldata, 0], ); // REVERT => NOT AUTHORIZED await expect(fractalModule.execTx(txData)).to.be.revertedWithCustomError( fractalModule, - "Unauthorized" + 'Unauthorized', ); // OWNER MAY EXECUTE await expect(fractalModule.connect(owner1).execTx(txData)).to.emit( gnosisSafe, - "ExecutionFromModuleSuccess" + 'ExecutionFromModuleSuccess', ); // Controller MAY EXECUTE await expect(fractalModule.connect(owner2).execTx(txData)).to.emit( gnosisSafe, - "ExecutionFromModuleSuccess" + 'ExecutionFromModuleSuccess', ); // REVERT => Execution Failure - await expect( - fractalModule.connect(owner1).execTx(txData) - ).to.be.revertedWithCustomError(fractalModule, "TxFailed"); - - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 0 + await expect(fractalModule.connect(owner1).execTx(txData)).to.be.revertedWithCustomError( + fractalModule, + 'TxFailed', ); + + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(owner1.address)).to.eq(1000); }); }); diff --git a/test/Fractal-Registry.test.ts b/test/Fractal-Registry.test.ts index 1d046fc0..f05ed7f6 100644 --- a/test/Fractal-Registry.test.ts +++ b/test/Fractal-Registry.test.ts @@ -1,15 +1,15 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import hre from "hardhat"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre from 'hardhat'; import { FractalRegistry, FractalRegistry__factory, KeyValuePairs, KeyValuePairs__factory, -} from "../typechain-types"; +} from '../typechain-types'; -describe("Fractal Registry", () => { +describe('Fractal Registry', () => { // Deployed contracts let fractalRegistry: FractalRegistry; let keyValues: KeyValuePairs; @@ -27,43 +27,41 @@ describe("Fractal Registry", () => { keyValues = await new KeyValuePairs__factory(deployer).deploy(); }); - it("A DAO can update its name", async () => { - await expect(fractalRegistry.connect(dao1).updateDAOName("Decent Dawgs")) - .to.emit(fractalRegistry, "FractalNameUpdated") - .withArgs(dao1.address, "Decent Dawgs"); + it('A DAO can update its name', async () => { + await expect(fractalRegistry.connect(dao1).updateDAOName('Decent Dawgs')) + .to.emit(fractalRegistry, 'FractalNameUpdated') + .withArgs(dao1.address, 'Decent Dawgs'); - await expect(fractalRegistry.connect(dao2).updateDAOName("Decent Dawgs2")) - .to.emit(fractalRegistry, "FractalNameUpdated") - .withArgs(dao2.address, "Decent Dawgs2"); + await expect(fractalRegistry.connect(dao2).updateDAOName('Decent Dawgs2')) + .to.emit(fractalRegistry, 'FractalNameUpdated') + .withArgs(dao2.address, 'Decent Dawgs2'); }); - it("A DAO can update its name multiple times", async () => { - await expect(fractalRegistry.connect(dao1).updateDAOName("Decent Dawgs")) - .to.emit(fractalRegistry, "FractalNameUpdated") - .withArgs(dao1.address, "Decent Dawgs"); + it('A DAO can update its name multiple times', async () => { + await expect(fractalRegistry.connect(dao1).updateDAOName('Decent Dawgs')) + .to.emit(fractalRegistry, 'FractalNameUpdated') + .withArgs(dao1.address, 'Decent Dawgs'); - await expect(fractalRegistry.connect(dao1).updateDAOName("Decent Dawgs2")) - .to.emit(fractalRegistry, "FractalNameUpdated") - .withArgs(dao1.address, "Decent Dawgs2"); + await expect(fractalRegistry.connect(dao1).updateDAOName('Decent Dawgs2')) + .to.emit(fractalRegistry, 'FractalNameUpdated') + .withArgs(dao1.address, 'Decent Dawgs2'); }); - it("A DAO can declare its subDAO", async () => { + it('A DAO can declare its subDAO', async () => { await expect(fractalRegistry.connect(dao1).declareSubDAO(dao2.address)) - .to.emit(fractalRegistry, "FractalSubDAODeclared") + .to.emit(fractalRegistry, 'FractalSubDAODeclared') .withArgs(dao1.address, dao2.address); }); - it("A DAO can declare arbitrary key/value pairs", async () => { - await expect( - keyValues.connect(dao1).updateValues(["twitter"], ["@awesome"]) - ) - .to.emit(keyValues, "ValueUpdated") - .withArgs(dao1.address, "twitter", "@awesome"); + it('A DAO can declare arbitrary key/value pairs', async () => { + await expect(keyValues.connect(dao1).updateValues(['twitter'], ['@awesome'])) + .to.emit(keyValues, 'ValueUpdated') + .withArgs(dao1.address, 'twitter', '@awesome'); }); - it("KeyValuePairs reverts if unequal array lengths are passed to it", async () => { + it('KeyValuePairs reverts if unequal array lengths are passed to it', async () => { await expect( - keyValues.connect(dao1).updateValues(["twitter", "discord"], ["@awesome"]) - ).to.be.revertedWithCustomError(keyValues, "IncorrectValueCount"); + keyValues.connect(dao1).updateValues(['twitter', 'discord'], ['@awesome']), + ).to.be.revertedWithCustomError(keyValues, 'IncorrectValueCount'); }); }); diff --git a/test/GlobalSafeDeployments.test.ts b/test/GlobalSafeDeployments.test.ts index c9cb0144..30411035 100644 --- a/test/GlobalSafeDeployments.test.ts +++ b/test/GlobalSafeDeployments.test.ts @@ -1,3 +1,4 @@ +import hre from 'hardhat'; import { GnosisSafeProxyFactory, GnosisSafeProxyFactory__factory, @@ -9,8 +10,7 @@ import { GnosisSafeL2__factory, MockContract, MockContract__factory, -} from "../typechain-types"; -import hre from "hardhat"; +} from '../typechain-types'; let gnosisSafeProxyFactory: GnosisSafeProxyFactory; let moduleProxyFactory: ModuleProxyFactory; @@ -21,9 +21,7 @@ let mockContract: MockContract; beforeEach(async () => { const [deployer] = await hre.ethers.getSigners(); - gnosisSafeProxyFactory = await new GnosisSafeProxyFactory__factory( - deployer - ).deploy(); + gnosisSafeProxyFactory = await new GnosisSafeProxyFactory__factory(deployer).deploy(); moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); gnosisSafeL2Singleton = await new GnosisSafeL2__factory(deployer).deploy(); multiSendCallOnly = await new MultiSendCallOnly__factory(deployer).deploy(); diff --git a/test/MultisigFreezeGuard-ERC20FreezeVoting.test.ts b/test/MultisigFreezeGuard-ERC20FreezeVoting.test.ts index c355d6ea..9eaab44d 100644 --- a/test/MultisigFreezeGuard-ERC20FreezeVoting.test.ts +++ b/test/MultisigFreezeGuard-ERC20FreezeVoting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import hre from "hardhat"; -import { ethers } from "ethers"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { VotesERC20, VotesERC20__factory, @@ -12,21 +10,22 @@ import { MultisigFreezeGuard__factory, GnosisSafeL2__factory, GnosisSafeL2, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, safeSignTypedData, predictGnosisSafeAddress, calculateProxyAddress, -} from "./helpers"; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; +import time from './time'; -describe("Child Multisig DAO with Azorius Parent", () => { +describe('Child Multisig DAO with Azorius Parent', () => { // Deployed contracts let gnosisSafe: GnosisSafeL2; let freezeGuardMastercopy: MultisigFreezeGuard; @@ -49,20 +48,11 @@ describe("Child Multisig DAO with Azorius Parent", () => { let createGnosisSetupCalldata: string; const threshold = 2; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { - [ - deployer, - owner1, - owner2, - owner3, - tokenVetoer1, - tokenVetoer2, - freezeGuardOwner, - ] = await hre.ethers.getSigners(); + [deployer, owner1, owner2, owner3, tokenVetoer1, tokenVetoer2, freezeGuardOwner] = + await hre.ethers.getSigners(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const moduleProxyFactory = getModuleProxyFactory(); @@ -70,7 +60,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ [owner1.address, owner2.address, owner3.address], threshold, ethers.ZeroAddress, @@ -85,22 +75,19 @@ describe("Child Multisig DAO with Azorius Parent", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, - saltNum + saltNum, ); // Get Gnosis Safe contract // eslint-disable-next-line camelcase - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); // Deploy token mastercopy votesERC20Mastercopy = await new VotesERC20__factory(deployer).deploy(); @@ -108,127 +95,113 @@ describe("Child Multisig DAO with Azorius Parent", () => { const abiCoder = new ethers.AbiCoder(); // encode data const votesERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], + ['string', 'string', 'address[]', 'uint256[]'], [ - "DCNT", - "DCNT", - [ - tokenVetoer1.address, - tokenVetoer2.address, - await gnosisSafe.getAddress(), - ], + 'DCNT', + 'DCNT', + [tokenVetoer1.address, tokenVetoer2.address, await gnosisSafe.getAddress()], [500, 600, 1000], - ] + ], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), votesERC20SetupData, - "10031021" + '10031021', ); const predictedVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), votesERC20SetupData, - "10031021" + '10031021', ); - votesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedVotesERC20Address - ); + votesERC20 = await hre.ethers.getContractAt('VotesERC20', predictedVotesERC20Address); // Vetoers delegate their votes to themselves await votesERC20.connect(tokenVetoer1).delegate(tokenVetoer1.address); await votesERC20.connect(tokenVetoer2).delegate(tokenVetoer2.address); // Deploy ERC20FreezeVoting mastercopy contract - freezeVotingMastercopy = await new ERC20FreezeVoting__factory( - deployer - ).deploy(); + freezeVotingMastercopy = await new ERC20FreezeVoting__factory(deployer).deploy(); // Initialize FreezeVoting contract const freezeVotingSetupData = // eslint-disable-next-line camelcase - ERC20FreezeVoting__factory.createInterface().encodeFunctionData("setUp", [ + ERC20FreezeVoting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "uint256", "uint32", "uint32", "address"], + ['address', 'uint256', 'uint32', 'uint32', 'address'], [ freezeGuardOwner.address, 1090, // freeze votes threshold 10, // freeze proposal period 200, // freeze period await votesERC20.getAddress(), - ] + ], ), ]); await moduleProxyFactory.deployModule( await freezeVotingMastercopy.getAddress(), freezeVotingSetupData, - "10031021" + '10031021', ); const predictedFreezeVotingAddress = await calculateProxyAddress( moduleProxyFactory, await freezeVotingMastercopy.getAddress(), freezeVotingSetupData, - "10031021" + '10031021', ); freezeVoting = await hre.ethers.getContractAt( - "ERC20FreezeVoting", - predictedFreezeVotingAddress + 'ERC20FreezeVoting', + predictedFreezeVotingAddress, ); // Deploy FreezeGuard mastercopy contract - freezeGuardMastercopy = await new MultisigFreezeGuard__factory( - deployer - ).deploy(); + freezeGuardMastercopy = await new MultisigFreezeGuard__factory(deployer).deploy(); // Deploy MultisigFreezeGuard contract with a 60 block timelock period, and a 60 block execution period const freezeGuardSetupData = // eslint-disable-next-line camelcase - MultisigFreezeGuard__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["uint32", "uint32", "address", "address", "address"], - [ - 60, // Timelock period - 60, // Execution period - freezeGuardOwner.address, - await freezeVoting.getAddress(), - await gnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeGuard__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['uint32', 'uint32', 'address', 'address', 'address'], + [ + 60, // Timelock period + 60, // Execution period + freezeGuardOwner.address, + await freezeVoting.getAddress(), + await gnosisSafe.getAddress(), + ], + ), + ]); await moduleProxyFactory.deployModule( await freezeGuardMastercopy.getAddress(), freezeGuardSetupData, - "10031021" + '10031021', ); const predictedFreezeGuardAddress = await calculateProxyAddress( moduleProxyFactory, await freezeGuardMastercopy.getAddress(), freezeGuardSetupData, - "10031021" + '10031021', ); freezeGuard = await hre.ethers.getContractAt( - "MultisigFreezeGuard", - predictedFreezeGuardAddress + 'MultisigFreezeGuard', + predictedFreezeGuardAddress, ); // Create transaction to set the guard address - const setGuardData = gnosisSafe.interface.encodeFunctionData("setGuard", [ + const setGuardData = gnosisSafe.interface.encodeFunctionData('setGuard', [ await freezeGuard.getAddress(), ]); @@ -256,18 +229,16 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); // Gnosis Safe received the 1,000 tokens - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 1000 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(1000); }); - describe("FreezeGuard Functionality", () => { - it("Freeze parameters correctly setup", async () => { + describe('FreezeGuard Functionality', () => { + it('Freeze parameters correctly setup', async () => { // Frozen Params init correctly expect(await freezeVoting.freezeVotesThreshold()).to.eq(1090); expect(await freezeVoting.freezeProposalPeriod()).to.eq(10); @@ -275,7 +246,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { expect(await freezeVoting.owner()).to.eq(freezeGuardOwner.address); }); - it("Updates state properly due to freeze actions", async () => { + it('Updates state properly due to freeze actions', async () => { expect(await freezeVoting.freezeProposalVoteCount()).to.eq(0); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(0); @@ -283,21 +254,19 @@ describe("Child Multisig DAO with Azorius Parent", () => { await freezeVoting.connect(tokenVetoer1).castFreezeVote(); expect(await freezeVoting.isFrozen()).to.eq(false); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); - const latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + const latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); await freezeVoting.connect(tokenVetoer2).castFreezeVote(); expect(await freezeVoting.isFrozen()).to.eq(true); }); - it("A transaction can be timelocked and executed", async () => { + it('A transaction can be timelocked and executed', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -323,19 +292,16 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); - const latestBlock = await hre.ethers.provider.getBlock("latest"); + const latestBlock = await hre.ethers.provider.getBlock('latest'); - const signaturesHash = ethers.solidityPackedKeccak256( - ["bytes"], - [signatureBytes] - ); + const signaturesHash = ethers.solidityPackedKeccak256(['bytes'], [signatureBytes]); - expect( - await freezeGuard.getTransactionTimelockedBlock(signaturesHash) - ).to.eq(latestBlock!.number); + expect(await freezeGuard.getTransactionTimelockedBlock(signaturesHash)).to.eq( + latestBlock!.number, + ); // Move time forward to elapse timelock period await time.advanceBlocks(60); @@ -350,21 +316,19 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes + signatureBytes, ); - expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq( - 0 - ); + expect(await votesERC20.balanceOf(await gnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(deployer.address)).to.eq(1000); }); it("A transaction cannot be executed if it hasn't yet been timelocked", async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -390,17 +354,17 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWithCustomError(freezeGuard, "NotTimelocked"); + signatureBytes, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'NotTimelocked'); }); it("A transaction cannot be timelocked if the signatures aren't valid", async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -425,17 +389,17 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce - ) - ).to.be.revertedWith("GS020"); + tx.nonce, + ), + ).to.be.revertedWith('GS020'); }); - it("A transaction cannot be executed if the timelock period has not ended yet", async () => { + it('A transaction cannot be executed if the timelock period has not ended yet', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -461,7 +425,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); await expect( @@ -475,12 +439,12 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWithCustomError(freezeGuard, "Timelocked"); + signatureBytes, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'Timelocked'); }); - it("A DAO may execute txs during a the freeze proposal period if the freeze threshold is not met", async () => { + it('A DAO may execute txs during a the freeze proposal period if the freeze threshold is not met', async () => { // Vetoer 1 casts 500 freeze votes await freezeVoting.connect(tokenVetoer1).castFreezeVote(); @@ -488,10 +452,10 @@ describe("Child Multisig DAO with Azorius Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(false); // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -517,7 +481,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -534,12 +498,12 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes1, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Casting a vote after the freeze voting period resets state", async () => { + it('Casting a vote after the freeze voting period resets state', async () => { expect(await freezeVoting.freezeProposalVoteCount()).to.eq(0); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(0); @@ -547,32 +511,28 @@ describe("Child Multisig DAO with Azorius Parent", () => { await freezeVoting.connect(tokenVetoer1).castFreezeVote(); expect(await freezeVoting.isFrozen()).to.eq(false); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); - let latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + let latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); // Move time forward to elapse freeze proposal period await time.advanceBlocks(10); await freezeVoting.connect(tokenVetoer1).castFreezeVote(); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); - latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); expect(await freezeVoting.isFrozen()).to.eq(false); }); - it("A user cannot vote twice to freeze a dao during the same voting period", async () => { + it('A user cannot vote twice to freeze a dao during the same voting period', async () => { await freezeVoting.connect(tokenVetoer1).castFreezeVote(); await expect( - freezeVoting.connect(tokenVetoer1).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "AlreadyVoted"); + freezeVoting.connect(tokenVetoer1).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'AlreadyVoted'); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); }); - it("An unfrozen DAO may not execute a previously passed transaction", async () => { + it('An unfrozen DAO may not execute a previously passed transaction', async () => { // Vetoer 1 casts 500 freeze votes await freezeVoting.connect(tokenVetoer1).castFreezeVote(); // Vetoer 2 casts 600 freeze votes @@ -582,10 +542,10 @@ describe("Child Multisig DAO with Azorius Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(true); // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -611,7 +571,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -628,9 +588,9 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Move time forward to elapse freeze period await time.advanceBlocks(140); @@ -648,12 +608,12 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "Expired"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'Expired'); }); - it("Unfrozen DAOs may execute txs", async () => { + it('Unfrozen DAOs may execute txs', async () => { // Vetoer 1 casts 500 freeze votes await freezeVoting.connect(tokenVetoer1).castFreezeVote(); // Vetoer 2 casts 600 freeze votes @@ -665,10 +625,10 @@ describe("Child Multisig DAO with Azorius Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(false); // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -694,7 +654,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -712,98 +672,94 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes1, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("You must have voting weight to cast a freeze vote", async () => { + it('You must have voting weight to cast a freeze vote', async () => { await expect( - freezeVoting.connect(freezeGuardOwner).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + freezeVoting.connect(freezeGuardOwner).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); freezeVoting.connect(tokenVetoer1).castFreezeVote(); await expect( - freezeVoting.connect(freezeGuardOwner).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + freezeVoting.connect(freezeGuardOwner).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); }); - it("Only owner methods must be called by vetoGuard owner", async () => { - await expect( - freezeVoting.connect(tokenVetoer1).unfreeze() - ).to.be.revertedWith("Ownable: caller is not the owner"); - await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + it('Only owner methods must be called by vetoGuard owner', async () => { + await expect(freezeVoting.connect(tokenVetoer1).unfreeze()).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezePeriod(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); + await expect(freezeVoting.connect(tokenVetoer1).updateFreezePeriod(0)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the freeze voting owner can update the freeze votes threshold", async () => { + it('Only the freeze voting owner can update the freeze votes threshold', async () => { expect(await freezeVoting.freezeVotesThreshold()).to.eq(1090); - await freezeVoting - .connect(freezeGuardOwner) - .updateFreezeVotesThreshold(2000); + await freezeVoting.connect(freezeGuardOwner).updateFreezeVotesThreshold(2000); expect(await freezeVoting.freezeVotesThreshold()).to.eq(2000); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(3000) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(3000), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Only the freeze voting owner can update the freeze proposal period", async () => { + it('Only the freeze voting owner can update the freeze proposal period', async () => { expect(await freezeVoting.freezeProposalPeriod()).to.eq(10); - await freezeVoting - .connect(freezeGuardOwner) - .updateFreezeProposalPeriod(12); + await freezeVoting.connect(freezeGuardOwner).updateFreezeProposalPeriod(12); expect(await freezeVoting.freezeProposalPeriod()).to.eq(12); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(14) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(14), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Only the freeze voting owner can update the freeze period", async () => { + it('Only the freeze voting owner can update the freeze period', async () => { expect(await freezeVoting.freezePeriod()).to.eq(200); await freezeVoting.connect(freezeGuardOwner).updateFreezePeriod(300); expect(await freezeVoting.freezePeriod()).to.eq(300); - await expect( - freezeVoting.connect(tokenVetoer1).updateFreezePeriod(400) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(freezeVoting.connect(tokenVetoer1).updateFreezePeriod(400)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the freeze guard owner can update the timelock period", async () => { + it('Only the freeze guard owner can update the timelock period', async () => { expect(await freezeGuard.timelockPeriod()).to.eq(60); await freezeGuard.connect(freezeGuardOwner).updateTimelockPeriod(70); expect(await freezeGuard.timelockPeriod()).to.eq(70); - await expect( - freezeGuard.connect(tokenVetoer1).updateTimelockPeriod(80) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(freezeGuard.connect(tokenVetoer1).updateTimelockPeriod(80)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the freeze guard owner can update the execution period", async () => { + it('Only the freeze guard owner can update the execution period', async () => { expect(await freezeGuard.executionPeriod()).to.eq(60); await freezeGuard.connect(freezeGuardOwner).updateExecutionPeriod(80); expect(await freezeGuard.executionPeriod()).to.eq(80); - await expect( - freezeGuard.connect(tokenVetoer1).updateExecutionPeriod(90) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(freezeGuard.connect(tokenVetoer1).updateExecutionPeriod(90)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); }); }); diff --git a/test/MultisigFreezeGuard-ERC721FreezeVoting.test.ts b/test/MultisigFreezeGuard-ERC721FreezeVoting.test.ts index 4263c337..6fc5ccb3 100644 --- a/test/MultisigFreezeGuard-ERC721FreezeVoting.test.ts +++ b/test/MultisigFreezeGuard-ERC721FreezeVoting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import hre from "hardhat"; -import { ethers } from "ethers"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { ERC721FreezeVoting, ERC721FreezeVoting__factory, @@ -17,21 +15,22 @@ import { Azorius, GnosisSafeL2__factory, GnosisSafeL2, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, safeSignTypedData, predictGnosisSafeAddress, calculateProxyAddress, -} from "./helpers"; -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; +import time from './time'; -describe("Child Multisig DAO with Azorius Parent", () => { +describe('Child Multisig DAO with Azorius Parent', () => { // Deployed contracts let gnosisSafe: GnosisSafeL2; let freezeGuardMastercopy: MultisigFreezeGuard; @@ -60,27 +59,15 @@ describe("Child Multisig DAO with Azorius Parent", () => { let createGnosisSetupCalldata: string; const threshold = 2; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); - - async function mintNFT( - contract: MockERC721, - receiver: SignerWithAddress - ): Promise { + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); + + async function mintNFT(contract: MockERC721, receiver: SignerWithAddress): Promise { await contract.connect(receiver).mint(receiver.address); } beforeEach(async () => { - [ - deployer, - owner1, - owner2, - owner3, - tokenVetoer1, - tokenVetoer2, - freezeGuardOwner, - ] = await hre.ethers.getSigners(); + [deployer, owner1, owner2, owner3, tokenVetoer1, tokenVetoer2, freezeGuardOwner] = + await hre.ethers.getSigners(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const moduleProxyFactory = getModuleProxyFactory(); @@ -88,7 +75,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { createGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ [owner1.address, owner2.address, owner3.address], threshold, ethers.ZeroAddress, @@ -103,22 +90,19 @@ describe("Child Multisig DAO with Azorius Parent", () => { createGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createGnosisSetupCalldata, - saltNum + saltNum, ); // Get Gnosis Safe contract // eslint-disable-next-line camelcase - gnosisSafe = GnosisSafeL2__factory.connect( - predictedGnosisSafeAddress, - deployer - ); + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); const abiCoder = new ethers.AbiCoder(); // encode data @@ -132,18 +116,16 @@ describe("Child Multisig DAO with Azorius Parent", () => { vetoer1Ids = [0]; vetoer2Ids = [1, 2]; - mintNFTData = mockNFT.interface.encodeFunctionData("mint", [ - deployer.address, - ]); + mintNFTData = mockNFT.interface.encodeFunctionData('mint', [deployer.address]); // Deploy Azorius module azoriusMastercopy = await new Azorius__factory(deployer).deploy(); const azoriusSetupCalldata = // eslint-disable-next-line camelcase - Azorius__factory.createInterface().encodeFunctionData("setUp", [ + Azorius__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "address", "address", "address[]", "uint32", "uint32"], + ['address', 'address', 'address', 'address[]', 'uint32', 'uint32'], [ owner1.address, await gnosisSafe.getAddress(), @@ -151,164 +133,149 @@ describe("Child Multisig DAO with Azorius Parent", () => { [], 60, // timelock period in blocks 60, // execution period in blocks - ] + ], ), ]); await moduleProxyFactory.deployModule( await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); const predictedAzoriusAddress = await calculateProxyAddress( moduleProxyFactory, await azoriusMastercopy.getAddress(), azoriusSetupCalldata, - "10031021" + '10031021', ); - azorius = await hre.ethers.getContractAt( - "Azorius", - predictedAzoriusAddress - ); + azorius = await hre.ethers.getContractAt('Azorius', predictedAzoriusAddress); // Deploy Linear ERC721 Voting Mastercopy - linearERC721VotingMastercopy = await new LinearERC721Voting__factory( - deployer - ).deploy(); + linearERC721VotingMastercopy = await new LinearERC721Voting__factory(deployer).deploy(); const linearERC721VotingSetupCalldata = // eslint-disable-next-line camelcase - LinearERC721Voting__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - [ - "address", - "address[]", - "uint256[]", - "address", - "uint32", - "uint256", - "uint256", - "uint256", - ], - [ - owner1.address, // owner - [await mockNFT.getAddress()], // NFT addresses - [500], // NFT weights - await azorius.getAddress(), // Azorius module - 60, // voting period in blocks - 2, // quorom threshold - 2, // proposer threshold - 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) - ] - ), - ] - ); + LinearERC721Voting__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + [ + 'address', + 'address[]', + 'uint256[]', + 'address', + 'uint32', + 'uint256', + 'uint256', + 'uint256', + ], + [ + owner1.address, // owner + [await mockNFT.getAddress()], // NFT addresses + [500], // NFT weights + await azorius.getAddress(), // Azorius module + 60, // voting period in blocks + 2, // quorom threshold + 2, // proposer threshold + 500000, // basis numerator, denominator is 1,000,000, so basis percentage is 50% (simple majority) + ], + ), + ]); await moduleProxyFactory.deployModule( await linearERC721VotingMastercopy.getAddress(), linearERC721VotingSetupCalldata, - "10031021" + '10031021', ); const predictedlinearERC721VotingAddress = await calculateProxyAddress( moduleProxyFactory, await linearERC721VotingMastercopy.getAddress(), linearERC721VotingSetupCalldata, - "10031021" + '10031021', ); linearERC721Voting = await hre.ethers.getContractAt( - "LinearERC721Voting", - predictedlinearERC721VotingAddress + 'LinearERC721Voting', + predictedlinearERC721VotingAddress, ); // Deploy ERC721FreezeVoting mastercopy contract - freezeVotingMastercopy = await new ERC721FreezeVoting__factory( - deployer - ).deploy(); + freezeVotingMastercopy = await new ERC721FreezeVoting__factory(deployer).deploy(); // Initialize FreezeVoting contract const freezeVotingSetupData = // eslint-disable-next-line camelcase - ERC20FreezeVoting__factory.createInterface().encodeFunctionData("setUp", [ + ERC20FreezeVoting__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["address", "uint256", "uint32", "uint32", "address"], + ['address', 'uint256', 'uint32', 'uint32', 'address'], [ freezeGuardOwner.address, 501, // freeze votes threshold 10, // freeze proposal period 200, // freeze period await linearERC721Voting.getAddress(), // strategy address - ] + ], ), ]); await moduleProxyFactory.deployModule( await freezeVotingMastercopy.getAddress(), freezeVotingSetupData, - "10031021" + '10031021', ); const predictedFreezeVotingAddress = await calculateProxyAddress( moduleProxyFactory, await freezeVotingMastercopy.getAddress(), freezeVotingSetupData, - "10031021" + '10031021', ); freezeVoting = await hre.ethers.getContractAt( - "ERC721FreezeVoting", - predictedFreezeVotingAddress + 'ERC721FreezeVoting', + predictedFreezeVotingAddress, ); // Deploy FreezeGuard mastercopy contract - freezeGuardMastercopy = await new MultisigFreezeGuard__factory( - deployer - ).deploy(); + freezeGuardMastercopy = await new MultisigFreezeGuard__factory(deployer).deploy(); // Deploy MultisigFreezeGuard contract with a 60 block timelock period, and a 60 block execution period const freezeGuardSetupData = // eslint-disable-next-line camelcase - MultisigFreezeGuard__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["uint32", "uint32", "address", "address", "address"], - [ - 60, // Timelock period - 60, // Execution period - freezeGuardOwner.address, - await freezeVoting.getAddress(), - await gnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeGuard__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['uint32', 'uint32', 'address', 'address', 'address'], + [ + 60, // Timelock period + 60, // Execution period + freezeGuardOwner.address, + await freezeVoting.getAddress(), + await gnosisSafe.getAddress(), + ], + ), + ]); await moduleProxyFactory.deployModule( await freezeGuardMastercopy.getAddress(), freezeGuardSetupData, - "10031021" + '10031021', ); const predictedFreezeGuardAddress = await calculateProxyAddress( moduleProxyFactory, await freezeGuardMastercopy.getAddress(), freezeGuardSetupData, - "10031021" + '10031021', ); freezeGuard = await hre.ethers.getContractAt( - "MultisigFreezeGuard", - predictedFreezeGuardAddress + 'MultisigFreezeGuard', + predictedFreezeGuardAddress, ); // Create transaction to set the guard address - const setGuardData = gnosisSafe.interface.encodeFunctionData("setGuard", [ + const setGuardData = gnosisSafe.interface.encodeFunctionData('setGuard', [ await freezeGuard.getAddress(), ]); @@ -336,13 +303,13 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - describe("FreezeGuard Functionality", () => { - it("Freeze parameters correctly setup", async () => { + describe('FreezeGuard Functionality', () => { + it('Freeze parameters correctly setup', async () => { // Frozen Params init correctly expect(await freezeVoting.freezeVotesThreshold()).to.eq(501); expect(await freezeVoting.freezeProposalPeriod()).to.eq(10); @@ -350,34 +317,28 @@ describe("Child Multisig DAO with Azorius Parent", () => { expect(await freezeVoting.owner()).to.eq(freezeGuardOwner.address); }); - it("Updates state properly due to freeze actions", async () => { + it('Updates state properly due to freeze actions', async () => { expect(await freezeVoting.freezeProposalVoteCount()).to.eq(0); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(0); // Vetoer 1 casts 500 freeze votes await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); expect(await freezeVoting.isFrozen()).to.eq(false); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); - const latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + const latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); await freezeVoting .connect(tokenVetoer2) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress(), await mockNFT.getAddress()], - vetoer2Ids - ); + [ + 'castFreezeVote(address[],uint256[])' + ]([await mockNFT.getAddress(), await mockNFT.getAddress()], vetoer2Ids); expect(await freezeVoting.isFrozen()).to.eq(true); }); - it("A transaction can be timelocked and executed", async () => { + it('A transaction can be timelocked and executed', async () => { const tx = buildSafeTransaction({ to: await mockNFT.getAddress(), data: mintNFTData, @@ -402,19 +363,16 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); - const latestBlock = await hre.ethers.provider.getBlock("latest"); + const latestBlock = await hre.ethers.provider.getBlock('latest'); - const signaturesHash = ethers.solidityPackedKeccak256( - ["bytes"], - [signatureBytes] - ); + const signaturesHash = ethers.solidityPackedKeccak256(['bytes'], [signatureBytes]); - expect( - await freezeGuard.getTransactionTimelockedBlock(signaturesHash) - ).to.eq(latestBlock!.number); + expect(await freezeGuard.getTransactionTimelockedBlock(signaturesHash)).to.eq( + latestBlock!.number, + ); // Move time forward to elapse timelock period await time.advanceBlocks(60); @@ -429,7 +387,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes + signatureBytes, ); expect(await mockNFT.balanceOf(deployer.address)).to.eq(1); @@ -460,9 +418,9 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWithCustomError(freezeGuard, "NotTimelocked"); + signatureBytes, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'NotTimelocked'); }); it("A transaction cannot be timelocked if the signatures aren't valid", async () => { @@ -489,12 +447,12 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce - ) - ).to.be.revertedWith("GS020"); + tx.nonce, + ), + ).to.be.revertedWith('GS020'); }); - it("A transaction cannot be executed if the timelock period has not ended yet", async () => { + it('A transaction cannot be executed if the timelock period has not ended yet', async () => { const tx = buildSafeTransaction({ to: await mockNFT.getAddress(), data: mintNFTData, @@ -519,7 +477,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); await expect( @@ -533,19 +491,16 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWithCustomError(freezeGuard, "Timelocked"); + signatureBytes, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'Timelocked'); }); - it("A DAO may execute txs during a the freeze proposal period if the freeze threshold is not met", async () => { + it('A DAO may execute txs during a the freeze proposal period if the freeze threshold is not met', async () => { // Vetoer 1 casts 500 freeze votes await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); // Check that the DAO has been frozen expect(await freezeVoting.isFrozen()).to.eq(false); @@ -574,7 +529,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -591,79 +546,59 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes1, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("Casting a vote after the freeze voting period resets state", async () => { + it('Casting a vote after the freeze voting period resets state', async () => { expect(await freezeVoting.freezeProposalVoteCount()).to.eq(0); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(0); // Vetoer 1 casts 500 freeze votes await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); expect(await freezeVoting.isFrozen()).to.eq(false); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); - let latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + let latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); // Move time forward to elapse freeze proposal period await time.advanceBlocks(10); await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); - latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); expect(await freezeVoting.isFrozen()).to.eq(false); }); - it("A user cannot vote twice to freeze a dao during the same voting period", async () => { + it('A user cannot vote twice to freeze a dao during the same voting period', async () => { await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); await expect( freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ) - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(500); }); - it("An unfrozen DAO may not execute a previously passed transaction", async () => { + it('An unfrozen DAO may not execute a previously passed transaction', async () => { // Vetoer 1 casts 500 freeze votes await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); // Vetoer 2 casts 1000 freeze votes await freezeVoting .connect(tokenVetoer2) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress(), await mockNFT.getAddress()], - vetoer2Ids - ); + [ + 'castFreezeVote(address[],uint256[])' + ]([await mockNFT.getAddress(), await mockNFT.getAddress()], vetoer2Ids); // Check that the DAO has been frozen expect(await freezeVoting.isFrozen()).to.eq(true); @@ -692,7 +627,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -709,9 +644,9 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Move time forward to elapse freeze period await time.advanceBlocks(140); @@ -729,26 +664,22 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "Expired"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'Expired'); }); - it("Unfrozen DAOs may execute txs", async () => { + it('Unfrozen DAOs may execute txs', async () => { // Vetoer 1 casts 500 freeze votes await freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); // Vetoer 2 casts 1000 freeze votes await freezeVoting .connect(tokenVetoer2) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress(), await mockNFT.getAddress()], - vetoer2Ids - ); + [ + 'castFreezeVote(address[],uint256[])' + ]([await mockNFT.getAddress(), await mockNFT.getAddress()], vetoer2Ids); // Check that the DAO has been frozen expect(await freezeVoting.isFrozen()).to.eq(true); @@ -779,7 +710,7 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -797,113 +728,102 @@ describe("Child Multisig DAO with Azorius Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.emit(gnosisSafe, "ExecutionSuccess"); + signatureBytes1, + ), + ).to.emit(gnosisSafe, 'ExecutionSuccess'); }); - it("You must have voting weight to cast a freeze vote", async () => { + it('You must have voting weight to cast a freeze vote', async () => { await expect( freezeVoting .connect(freezeGuardOwner) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ) - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); freezeVoting .connect(tokenVetoer1) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress()], - vetoer1Ids - ); + ['castFreezeVote(address[],uint256[])']([await mockNFT.getAddress()], vetoer1Ids); await expect( freezeVoting .connect(freezeGuardOwner) - ["castFreezeVote(address[],uint256[])"]( - [await mockNFT.getAddress(), await mockNFT.getAddress()], - vetoer2Ids - ) - ).to.be.revertedWithCustomError(freezeVoting, "NoVotes()"); + [ + 'castFreezeVote(address[],uint256[])' + ]([await mockNFT.getAddress(), await mockNFT.getAddress()], vetoer2Ids), + ).to.be.revertedWithCustomError(freezeVoting, 'NoVotes()'); }); - it("Only owner methods must be called by vetoGuard owner", async () => { - await expect( - freezeVoting.connect(tokenVetoer1).unfreeze() - ).to.be.revertedWith("Ownable: caller is not the owner"); - await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + it('Only owner methods must be called by vetoGuard owner', async () => { + await expect(freezeVoting.connect(tokenVetoer1).unfreeze()).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezePeriod(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); + await expect(freezeVoting.connect(tokenVetoer1).updateFreezePeriod(0)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the freeze voting owner can update the freeze votes threshold", async () => { + it('Only the freeze voting owner can update the freeze votes threshold', async () => { expect(await freezeVoting.freezeVotesThreshold()).to.eq(501); - await freezeVoting - .connect(freezeGuardOwner) - .updateFreezeVotesThreshold(2000); + await freezeVoting.connect(freezeGuardOwner).updateFreezeVotesThreshold(2000); expect(await freezeVoting.freezeVotesThreshold()).to.eq(2000); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(3000) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeVotesThreshold(3000), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Only the freeze voting owner can update the freeze proposal period", async () => { + it('Only the freeze voting owner can update the freeze proposal period', async () => { expect(await freezeVoting.freezeProposalPeriod()).to.eq(10); - await freezeVoting - .connect(freezeGuardOwner) - .updateFreezeProposalPeriod(12); + await freezeVoting.connect(freezeGuardOwner).updateFreezeProposalPeriod(12); expect(await freezeVoting.freezeProposalPeriod()).to.eq(12); await expect( - freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(14) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(tokenVetoer1).updateFreezeProposalPeriod(14), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); - it("Only the freeze voting owner can update the freeze period", async () => { + it('Only the freeze voting owner can update the freeze period', async () => { expect(await freezeVoting.freezePeriod()).to.eq(200); await freezeVoting.connect(freezeGuardOwner).updateFreezePeriod(300); expect(await freezeVoting.freezePeriod()).to.eq(300); - await expect( - freezeVoting.connect(tokenVetoer1).updateFreezePeriod(400) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(freezeVoting.connect(tokenVetoer1).updateFreezePeriod(400)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the freeze guard owner can update the timelock period", async () => { + it('Only the freeze guard owner can update the timelock period', async () => { expect(await freezeGuard.timelockPeriod()).to.eq(60); await freezeGuard.connect(freezeGuardOwner).updateTimelockPeriod(70); expect(await freezeGuard.timelockPeriod()).to.eq(70); - await expect( - freezeGuard.connect(tokenVetoer1).updateTimelockPeriod(80) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(freezeGuard.connect(tokenVetoer1).updateTimelockPeriod(80)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); - it("Only the freeze guard owner can update the execution period", async () => { + it('Only the freeze guard owner can update the execution period', async () => { expect(await freezeGuard.executionPeriod()).to.eq(60); await freezeGuard.connect(freezeGuardOwner).updateExecutionPeriod(80); expect(await freezeGuard.executionPeriod()).to.eq(80); - await expect( - freezeGuard.connect(tokenVetoer1).updateExecutionPeriod(90) - ).to.be.revertedWith("Ownable: caller is not the owner"); + await expect(freezeGuard.connect(tokenVetoer1).updateExecutionPeriod(90)).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); }); }); }); diff --git a/test/MultisigFreezeGuard-MultisigFreezeVoting.test.ts b/test/MultisigFreezeGuard-MultisigFreezeVoting.test.ts index ba487c1e..015fc07f 100644 --- a/test/MultisigFreezeGuard-MultisigFreezeVoting.test.ts +++ b/test/MultisigFreezeGuard-MultisigFreezeVoting.test.ts @@ -1,8 +1,6 @@ -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import { expect } from "chai"; -import hre from "hardhat"; -import { ethers } from "ethers"; -import time from "./time"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { VotesERC20, @@ -13,23 +11,23 @@ import { MultisigFreezeGuard__factory, GnosisSafeL2__factory, GnosisSafeL2, -} from "../typechain-types"; +} from '../typechain-types'; +import { + getGnosisSafeL2Singleton, + getGnosisSafeProxyFactory, + getModuleProxyFactory, +} from './GlobalSafeDeployments.test'; import { buildSignatureBytes, buildSafeTransaction, safeSignTypedData, predictGnosisSafeAddress, calculateProxyAddress, -} from "./helpers"; - -import { - getGnosisSafeL2Singleton, - getGnosisSafeProxyFactory, - getModuleProxyFactory, -} from "./GlobalSafeDeployments.test"; +} from './helpers'; +import time from './time'; -describe("Child Multisig DAO with Multisig Parent", () => { +describe('Child Multisig DAO with Multisig Parent', () => { // Deployed contracts let childGnosisSafe: GnosisSafeL2; let freezeGuard: MultisigFreezeGuard; @@ -53,9 +51,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { let createChildGnosisSetupCalldata: string; const threshold = 2; - const saltNum = BigInt( - "0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c" - ); + const saltNum = BigInt('0x856d90216588f9ffc124d1480a440e1c012c7a816952bc968d737bae5d4e139c'); beforeEach(async () => { [ @@ -75,12 +71,8 @@ describe("Child Multisig DAO with Multisig Parent", () => { createParentGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [ - parentMultisigOwner1.address, - parentMultisigOwner2.address, - parentMultisigOwner3.address, - ], + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ + [parentMultisigOwner1.address, parentMultisigOwner2.address, parentMultisigOwner3.address], threshold, ethers.ZeroAddress, ethers.ZeroHash, @@ -92,12 +84,8 @@ describe("Child Multisig DAO with Multisig Parent", () => { createChildGnosisSetupCalldata = // eslint-disable-next-line camelcase - GnosisSafeL2__factory.createInterface().encodeFunctionData("setup", [ - [ - childMultisigOwner1.address, - childMultisigOwner2.address, - childMultisigOwner3.address, - ], + GnosisSafeL2__factory.createInterface().encodeFunctionData('setup', [ + [childMultisigOwner1.address, childMultisigOwner2.address, childMultisigOwner3.address], threshold, ethers.ZeroAddress, ethers.ZeroHash, @@ -111,43 +99,40 @@ describe("Child Multisig DAO with Multisig Parent", () => { createParentGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); const predictedChildGnosisSafeAddress = await predictGnosisSafeAddress( createChildGnosisSetupCalldata, saltNum, await gnosisSafeL2Singleton.getAddress(), - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); // Deploy Parent Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createParentGnosisSetupCalldata, - saltNum + saltNum, ); // Deploy Child Gnosis Safe await gnosisSafeProxyFactory.createProxyWithNonce( await gnosisSafeL2Singleton.getAddress(), createChildGnosisSetupCalldata, - saltNum + saltNum, ); // Get Parent Gnosis Safe contract // eslint-disable-next-line camelcase const parentGnosisSafe = GnosisSafeL2__factory.connect( predictedParentGnosisSafeAddress, - deployer + deployer, ); // Get Child Gnosis Safe contract // eslint-disable-next-line camelcase - childGnosisSafe = GnosisSafeL2__factory.connect( - predictedChildGnosisSafeAddress, - deployer - ); + childGnosisSafe = GnosisSafeL2__factory.connect(predictedChildGnosisSafeAddress, deployer); // Deploy token mastercopy votesERC20Mastercopy = await new VotesERC20__factory(deployer).deploy(); @@ -155,119 +140,105 @@ describe("Child Multisig DAO with Multisig Parent", () => { const abiCoder = new ethers.AbiCoder(); // encode data const votesERC20SetupData = // eslint-disable-next-line camelcase - VotesERC20__factory.createInterface().encodeFunctionData("setUp", [ + VotesERC20__factory.createInterface().encodeFunctionData('setUp', [ abiCoder.encode( - ["string", "string", "address[]", "uint256[]"], - ["DCNT", "DCNT", [await childGnosisSafe.getAddress()], [1000]] + ['string', 'string', 'address[]', 'uint256[]'], + ['DCNT', 'DCNT', [await childGnosisSafe.getAddress()], [1000]], ), ]); await moduleProxyFactory.deployModule( await votesERC20Mastercopy.getAddress(), votesERC20SetupData, - "10031021" + '10031021', ); const predictedVotesERC20Address = await calculateProxyAddress( moduleProxyFactory, await votesERC20Mastercopy.getAddress(), votesERC20SetupData, - "10031021" + '10031021', ); - votesERC20 = await hre.ethers.getContractAt( - "VotesERC20", - predictedVotesERC20Address - ); + votesERC20 = await hre.ethers.getContractAt('VotesERC20', predictedVotesERC20Address); // Deploy MultisigFreezeVoting mastercopy contract - freezeVotingMastercopy = await new MultisigFreezeVoting__factory( - deployer - ).deploy(); + freezeVotingMastercopy = await new MultisigFreezeVoting__factory(deployer).deploy(); // Initialize MultisigFreezeVoting contract const freezeVotingSetupData = // eslint-disable-next-line camelcase - MultisigFreezeVoting__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["address", "uint256", "uint32", "uint32", "address"], - [ - freezeGuardOwner.address, - 2, // freeze votes threshold - 10, // freeze proposal duration in blocks - 200, // freeze duration in blocks - await parentGnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeVoting__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['address', 'uint256', 'uint32', 'uint32', 'address'], + [ + freezeGuardOwner.address, + 2, // freeze votes threshold + 10, // freeze proposal duration in blocks + 200, // freeze duration in blocks + await parentGnosisSafe.getAddress(), + ], + ), + ]); await moduleProxyFactory.deployModule( await freezeVotingMastercopy.getAddress(), freezeVotingSetupData, - "10031021" + '10031021', ); const predictedFreezeVotingAddress = await calculateProxyAddress( moduleProxyFactory, await freezeVotingMastercopy.getAddress(), freezeVotingSetupData, - "10031021" + '10031021', ); freezeVoting = await hre.ethers.getContractAt( - "MultisigFreezeVoting", - predictedFreezeVotingAddress + 'MultisigFreezeVoting', + predictedFreezeVotingAddress, ); // Deploy FreezeGuard mastercopy contract - const freezeGuardMastercopy = await new MultisigFreezeGuard__factory( - deployer - ).deploy(); + const freezeGuardMastercopy = await new MultisigFreezeGuard__factory(deployer).deploy(); // Deploy MultisigFreezeGuard contract with a 60 block timelock period and 60 block execution period const freezeGuardSetupData = // eslint-disable-next-line camelcase - MultisigFreezeGuard__factory.createInterface().encodeFunctionData( - "setUp", - [ - abiCoder.encode( - ["uint32", "uint32", "address", "address", "address"], - [ - 60, // Timelock period - 60, // Execution period - freezeGuardOwner.address, - await freezeVoting.getAddress(), - await childGnosisSafe.getAddress(), - ] - ), - ] - ); + MultisigFreezeGuard__factory.createInterface().encodeFunctionData('setUp', [ + abiCoder.encode( + ['uint32', 'uint32', 'address', 'address', 'address'], + [ + 60, // Timelock period + 60, // Execution period + freezeGuardOwner.address, + await freezeVoting.getAddress(), + await childGnosisSafe.getAddress(), + ], + ), + ]); await moduleProxyFactory.deployModule( await freezeGuardMastercopy.getAddress(), freezeGuardSetupData, - "10031021" + '10031021', ); const predictedFreezeGuardAddress = await calculateProxyAddress( moduleProxyFactory, await freezeGuardMastercopy.getAddress(), freezeGuardSetupData, - "10031021" + '10031021', ); freezeGuard = await hre.ethers.getContractAt( - "MultisigFreezeGuard", - predictedFreezeGuardAddress + 'MultisigFreezeGuard', + predictedFreezeGuardAddress, ); // Create transaction to set the guard address - const setGuardData = childGnosisSafe.interface.encodeFunctionData( - "setGuard", - [await freezeGuard.getAddress()] - ); + const setGuardData = childGnosisSafe.interface.encodeFunctionData('setGuard', [ + await freezeGuard.getAddress(), + ]); const tx = buildSafeTransaction({ to: await childGnosisSafe.getAddress(), @@ -293,18 +264,16 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.emit(childGnosisSafe, "ExecutionSuccess"); + signatureBytes, + ), + ).to.emit(childGnosisSafe, 'ExecutionSuccess'); // Gnosis Safe received the 1,000 tokens - expect( - await votesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(1000); + expect(await votesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(1000); }); - describe("MultisigFreezeGuard with MultisigFreezeVoting", () => { - it("Freeze vars set properly during init", async () => { + describe('MultisigFreezeGuard with MultisigFreezeVoting', () => { + it('Freeze vars set properly during init', async () => { // Frozen Params init correctly expect(await freezeVoting.freezeVotesThreshold()).to.eq(2); expect(await freezeVoting.freezeProposalPeriod()).to.eq(10); @@ -312,7 +281,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { expect(await freezeVoting.owner()).to.eq(freezeGuardOwner.address); }); - it("Updates state properly due to freeze actions", async () => { + it('Updates state properly due to freeze actions', async () => { expect(await freezeVoting.freezeProposalVoteCount()).to.eq(0); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(0); @@ -320,21 +289,19 @@ describe("Child Multisig DAO with Multisig Parent", () => { await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); expect(await freezeVoting.isFrozen()).to.eq(false); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(1); - const latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + const latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); await freezeVoting.connect(parentMultisigOwner2).castFreezeVote(); expect(await freezeVoting.isFrozen()).to.eq(true); }); - it("A transaction can be timelocked and executed", async () => { + it('A transaction can be timelocked and executed', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -360,7 +327,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); // Move time forward to elapse timelock period @@ -376,21 +343,19 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes + signatureBytes, ); - expect( - await votesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(0); + expect(await votesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(deployer.address)).to.eq(1000); }); - it("The same transaction must be timelocked separately if being executed more than once", async () => { + it('The same transaction must be timelocked separately if being executed more than once', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -416,7 +381,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); // Move time forward to elapse timelock period @@ -432,12 +397,10 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes + signatureBytes, ); - expect( - await votesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(0); + expect(await votesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(deployer.address)).to.eq(1000); await expect( @@ -451,17 +414,17 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWith("GS026"); + signatureBytes, + ), + ).to.be.revertedWith('GS026'); }); - it("The same transaction can be executed twice if it is timelocked separately", async () => { + it('The same transaction can be executed twice if it is timelocked separately', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 500] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 500, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -500,7 +463,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); await freezeGuard.timelockTransaction( @@ -514,7 +477,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx2.gasToken, tx2.refundReceiver, signatureBytes2, - tx2.nonce + tx2.nonce, ); // Move time forward to elapse timelock period @@ -531,7 +494,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 + signatureBytes1, ); // Execute the second transaction @@ -545,21 +508,19 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx2.gasPrice, tx2.gasToken, tx2.refundReceiver, - signatureBytes2 + signatureBytes2, ); - expect( - await votesERC20.balanceOf(await childGnosisSafe.getAddress()) - ).to.eq(0); + expect(await votesERC20.balanceOf(await childGnosisSafe.getAddress())).to.eq(0); expect(await votesERC20.balanceOf(deployer.address)).to.eq(1000); }); it("A transaction cannot be executed if it hasn't yet been timelocked", async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -585,17 +546,17 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWithCustomError(freezeGuard, "NotTimelocked"); + signatureBytes, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'NotTimelocked'); }); it("A transaction cannot be timelocked if the signatures aren't valid", async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -605,9 +566,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { }); // Only 1 signer signs, while the threshold is 2 - const sigs = [ - await safeSignTypedData(childMultisigOwner1, childGnosisSafe, tx), - ]; + const sigs = [await safeSignTypedData(childMultisigOwner1, childGnosisSafe, tx)]; const signatureBytes = buildSignatureBytes(sigs); await expect( @@ -622,17 +581,17 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce - ) - ).to.be.revertedWith("GS020"); + tx.nonce, + ), + ).to.be.revertedWith('GS020'); }); - it("A transaction cannot be executed if the timelock period has not ended yet", async () => { + it('A transaction cannot be executed if the timelock period has not ended yet', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -658,7 +617,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); await expect( @@ -672,22 +631,22 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasPrice, tx.gasToken, tx.refundReceiver, - signatureBytes - ) - ).to.be.revertedWithCustomError(freezeGuard, "Timelocked"); + signatureBytes, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'Timelocked'); }); - it("A frozen DAO cannot execute any transactions", async () => { + it('A frozen DAO cannot execute any transactions', async () => { // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); - const tokenTransferData2 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 999] - ); + const tokenTransferData2 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 999, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -726,7 +685,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Vetoer 1 casts 1 freeze vote @@ -755,9 +714,9 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Timelock tx2 await freezeGuard.timelockTransaction( @@ -771,7 +730,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx2.gasToken, tx2.refundReceiver, signatureBytes2, - tx2.nonce + tx2.nonce, ); // Move time forward to elapse timelock period @@ -788,22 +747,22 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx2.gasPrice, tx2.gasToken, tx2.refundReceiver, - signatureBytes2 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes2, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); }); - it("A frozen DAO automatically unfreezes after the freeze period has ended", async () => { + it('A frozen DAO automatically unfreezes after the freeze period has ended', async () => { // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); - const tokenTransferData2 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 999] - ); + const tokenTransferData2 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 999, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -842,7 +801,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Vetoer 1 casts 1 freeze vote @@ -871,9 +830,9 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Timelock tx2 await freezeGuard.timelockTransaction( @@ -887,7 +846,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx2.gasToken, tx2.refundReceiver, signatureBytes2, - tx2.nonce + tx2.nonce, ); // Move time forward to elapse timelock period @@ -904,9 +863,9 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx2.gasPrice, tx2.gasToken, tx2.refundReceiver, - signatureBytes2 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes2, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); expect(await freezeVoting.isFrozen()).to.eq(true); @@ -917,7 +876,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(false); }); - it("A DAO may execute txs during a freeze proposal period if the freeze threshold is not met", async () => { + it('A DAO may execute txs during a freeze proposal period if the freeze threshold is not met', async () => { // Vetoer 1 casts 1 freeze vote await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); @@ -925,10 +884,10 @@ describe("Child Multisig DAO with Multisig Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(false); // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -954,7 +913,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -971,12 +930,12 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.emit(childGnosisSafe, "ExecutionSuccess"); + signatureBytes1, + ), + ).to.emit(childGnosisSafe, 'ExecutionSuccess'); }); - it("Casting a vote after the freeze voting period resets state", async () => { + it('Casting a vote after the freeze voting period resets state', async () => { expect(await freezeVoting.freezeProposalVoteCount()).to.eq(0); expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(0); @@ -984,32 +943,28 @@ describe("Child Multisig DAO with Multisig Parent", () => { await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); expect(await freezeVoting.isFrozen()).to.eq(false); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(1); - let latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + let latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); // Move time forward to elapse freeze proposal period await time.advanceBlocks(20); await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(1); - latestBlock = await hre.ethers.provider.getBlock("latest"); - expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq( - latestBlock!.number - ); + latestBlock = await hre.ethers.provider.getBlock('latest'); + expect(await freezeVoting.freezeProposalCreatedBlock()).to.eq(latestBlock!.number); expect(await freezeVoting.isFrozen()).to.eq(false); }); - it("A user cannot vote twice to freeze a DAO during the same voting period", async () => { + it('A user cannot vote twice to freeze a DAO during the same voting period', async () => { await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); await expect( - freezeVoting.connect(parentMultisigOwner1).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "AlreadyVoted"); + freezeVoting.connect(parentMultisigOwner1).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'AlreadyVoted'); expect(await freezeVoting.freezeProposalVoteCount()).to.eq(1); }); - it("Previously Frozen DAOs may not execute TXs after execution period has elapsed", async () => { + it('Previously Frozen DAOs may not execute TXs after execution period has elapsed', async () => { // Vetoer 1 casts 1 freeze vote await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); // Vetoer 2 casts 1 freeze vote @@ -1019,10 +974,10 @@ describe("Child Multisig DAO with Multisig Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(true); // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -1048,7 +1003,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -1065,9 +1020,9 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "DAOFrozen()"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'DAOFrozen()'); // Move time forward to elapse freeze period await time.advanceBlocks(140); @@ -1087,12 +1042,12 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.be.revertedWithCustomError(freezeGuard, "Expired"); + signatureBytes1, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'Expired'); }); - it("Unfrozen DAOs may execute txs", async () => { + it('Unfrozen DAOs may execute txs', async () => { // Vetoer 1 casts 1 freeze vote await freezeVoting.connect(parentMultisigOwner1).castFreezeVote(); // Vetoer 2 casts 1 freeze vote @@ -1104,10 +1059,10 @@ describe("Child Multisig DAO with Multisig Parent", () => { expect(await freezeVoting.isFrozen()).to.eq(false); // Create transaction to set the guard address - const tokenTransferData1 = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData1 = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx1 = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -1133,7 +1088,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasToken, tx1.refundReceiver, signatureBytes1, - tx1.nonce + tx1.nonce, ); // Move time forward to elapse timelock period @@ -1151,17 +1106,17 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx1.gasPrice, tx1.gasToken, tx1.refundReceiver, - signatureBytes1 - ) - ).to.emit(childGnosisSafe, "ExecutionSuccess"); + signatureBytes1, + ), + ).to.emit(childGnosisSafe, 'ExecutionSuccess'); }); - it("A transaction cannot be timelocked twice", async () => { + it('A transaction cannot be timelocked twice', async () => { // Create transaction to set the guard address - const tokenTransferData = votesERC20.interface.encodeFunctionData( - "transfer", - [deployer.address, 1000] - ); + const tokenTransferData = votesERC20.interface.encodeFunctionData('transfer', [ + deployer.address, + 1000, + ]); const tx = buildSafeTransaction({ to: await votesERC20.getAddress(), @@ -1187,7 +1142,7 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce + tx.nonce, ); await expect( @@ -1202,30 +1157,30 @@ describe("Child Multisig DAO with Multisig Parent", () => { tx.gasToken, tx.refundReceiver, signatureBytes, - tx.nonce - ) - ).to.be.revertedWithCustomError(freezeGuard, "AlreadyTimelocked"); + tx.nonce, + ), + ).to.be.revertedWithCustomError(freezeGuard, 'AlreadyTimelocked'); }); - it("You must be a parent multisig owner to cast a freeze vote", async () => { + it('You must be a parent multisig owner to cast a freeze vote', async () => { await expect( - freezeVoting.connect(freezeGuardOwner).castFreezeVote() - ).to.be.revertedWithCustomError(freezeVoting, "NotOwner"); + freezeVoting.connect(freezeGuardOwner).castFreezeVote(), + ).to.be.revertedWithCustomError(freezeVoting, 'NotOwner'); }); - it("Only owner methods must be called by the owner", async () => { - await expect( - freezeVoting.connect(childMultisigOwner1).unfreeze() - ).to.be.revertedWith("Ownable: caller is not the owner"); + it('Only owner methods must be called by the owner', async () => { + await expect(freezeVoting.connect(childMultisigOwner1).unfreeze()).to.be.revertedWith( + 'Ownable: caller is not the owner', + ); await expect( - freezeVoting.connect(childMultisigOwner1).updateFreezeVotesThreshold(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(childMultisigOwner1).updateFreezeVotesThreshold(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); await expect( - freezeVoting.connect(childMultisigOwner1).updateFreezeProposalPeriod(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(childMultisigOwner1).updateFreezeProposalPeriod(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); await expect( - freezeVoting.connect(childMultisigOwner1).updateFreezePeriod(0) - ).to.be.revertedWith("Ownable: caller is not the owner"); + freezeVoting.connect(childMultisigOwner1).updateFreezePeriod(0), + ).to.be.revertedWith('Ownable: caller is not the owner'); }); }); }); diff --git a/test/helpers.ts b/test/helpers.ts index 6c291701..17826296 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,4 +1,5 @@ -import { ethers, solidityPackedKeccak256 } from "ethers"; +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import hre, { ethers } from 'hardhat'; import { ERC6551Registry, GnosisSafeL2, @@ -6,10 +7,8 @@ import { IAzorius, MockContract__factory, MockHatsAccount__factory, -} from "../typechain-types"; -import { getMockContract } from "./GlobalSafeDeployments.test"; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; -import hre from "hardhat"; +} from '../typechain-types'; +import { getMockContract } from './GlobalSafeDeployments.test'; export interface MetaTransaction { to: string; @@ -36,18 +35,18 @@ export const predictGnosisSafeAddress = async ( calldata: string, saltNum: string | bigint, singleton: string, - gnosisFactory: GnosisSafeProxyFactory + gnosisFactory: GnosisSafeProxyFactory, ): Promise => { return ethers.getCreate2Address( await gnosisFactory.getAddress(), ethers.solidityPackedKeccak256( - ["bytes", "uint256"], - [ethers.solidityPackedKeccak256(["bytes"], [calldata]), saltNum] + ['bytes', 'uint256'], + [ethers.solidityPackedKeccak256(['bytes'], [calldata]), saltNum], ), ethers.solidityPackedKeccak256( - ["bytes", "uint256"], - [await gnosisFactory.proxyCreationCode(), singleton] - ) + ['bytes', 'uint256'], + [await gnosisFactory.proxyCreationCode(), singleton], + ), ); }; @@ -55,33 +54,29 @@ export const calculateProxyAddress = async ( factory: ethers.BaseContract, masterCopy: string, initData: string, - saltNonce: string + saltNonce: string, ): Promise => { - const masterCopyAddress = masterCopy.toLowerCase().replace(/^0x/, ""); + const masterCopyAddress = masterCopy.toLowerCase().replace(/^0x/, ''); const byteCode = - "0x602d8060093d393df3363d3d373d3d3d363d73" + + '0x602d8060093d393df3363d3d373d3d3d363d73' + masterCopyAddress + - "5af43d82803e903d91602b57fd5bf3"; + '5af43d82803e903d91602b57fd5bf3'; const salt = ethers.solidityPackedKeccak256( - ["bytes32", "uint256"], - [ethers.solidityPackedKeccak256(["bytes"], [initData]), saltNonce] + ['bytes32', 'uint256'], + [ethers.solidityPackedKeccak256(['bytes'], [initData]), saltNonce], ); - return ethers.getCreate2Address( - await factory.getAddress(), - salt, - ethers.keccak256(byteCode) - ); + return ethers.getCreate2Address(await factory.getAddress(), salt, ethers.keccak256(byteCode)); }; export const safeSignTypedData = async ( signer: ethers.Signer, safe: ethers.BaseContract, - safeTx: SafeTransaction + safeTx: SafeTransaction, ): Promise => { if (!signer.provider) { - throw Error("Provider required to retrieve chainId"); + throw Error('Provider required to retrieve chainId'); } const cid = (await signer.provider.getNetwork()).chainId; const signerAddress = await signer.getAddress(); @@ -92,56 +87,34 @@ export const safeSignTypedData = async ( { // "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)" SafeTx: [ - { type: "address", name: "to" }, - { type: "uint256", name: "value" }, - { type: "bytes", name: "data" }, - { type: "uint8", name: "operation" }, - { type: "uint256", name: "safeTxGas" }, - { type: "uint256", name: "baseGas" }, - { type: "uint256", name: "gasPrice" }, - { type: "address", name: "gasToken" }, - { type: "address", name: "refundReceiver" }, - { type: "uint256", name: "nonce" }, + { type: 'address', name: 'to' }, + { type: 'uint256', name: 'value' }, + { type: 'bytes', name: 'data' }, + { type: 'uint8', name: 'operation' }, + { type: 'uint256', name: 'safeTxGas' }, + { type: 'uint256', name: 'baseGas' }, + { type: 'uint256', name: 'gasPrice' }, + { type: 'address', name: 'gasToken' }, + { type: 'address', name: 'refundReceiver' }, + { type: 'uint256', name: 'nonce' }, ], }, - safeTx + safeTx, ), }; }; export const buildSignatureBytes = (signatures: SafeSignature[]): string => { signatures.sort((left, right) => - left.signer.toLowerCase().localeCompare(right.signer.toLowerCase()) + left.signer.toLowerCase().localeCompare(right.signer.toLowerCase()), ); - let signatureBytes = "0x"; + let signatureBytes = '0x'; for (const sig of signatures) { signatureBytes += sig.data.slice(2); } return signatureBytes; }; -export const buildContractCall = async ( - contract: ethers.BaseContract, - method: string, - params: any[], - nonce: number, - delegateCall?: boolean, - overrides?: Partial -): Promise => { - const data = contract.interface.encodeFunctionData(method, params); - return buildSafeTransaction( - Object.assign( - { - to: await contract.getAddress(), - data, - operation: delegateCall ? 1 : 0, - nonce, - }, - overrides - ) - ); -}; - export const buildSafeTransaction = (template: { to: string; value?: bigint | number | string; @@ -157,7 +130,7 @@ export const buildSafeTransaction = (template: { return { to: template.to, value: template.value || 0, - data: template.data || "0x", + data: template.data || '0x', operation: template.operation || 0, safeTxGas: template.safeTxGas || 0, baseGas: template.baseGas || 0, @@ -168,47 +141,63 @@ export const buildSafeTransaction = (template: { }; }; +export const buildContractCall = async ( + contract: ethers.BaseContract, + method: string, + params: any[], + nonce: number, + delegateCall?: boolean, + overrides?: Partial, +): Promise => { + const data = contract.interface.encodeFunctionData(method, params); + return buildSafeTransaction( + Object.assign( + { + to: await contract.getAddress(), + data, + operation: delegateCall ? 1 : 0, + nonce, + }, + overrides, + ), + ); +}; + export const encodeMultiSend = (txs: MetaTransaction[]): string => { return ( - "0x" + + '0x' + txs - .map((tx) => { + .map(tx => { const data = ethers.getBytes(tx.data); const encoded = ethers.solidityPacked( - ["uint8", "address", "uint256", "uint256", "bytes"], - [tx.operation, tx.to, tx.value, data.length, data] + ['uint8', 'address', 'uint256', 'uint256', 'bytes'], + [tx.operation, tx.to, tx.value, data.length, data], ); return encoded.slice(2); }) - .join("") + .join('') ); }; -export const mockTransaction = - async (): Promise => { - return { - to: await getMockContract().getAddress(), - value: 0n, - // eslint-disable-next-line camelcase - data: MockContract__factory.createInterface().encodeFunctionData( - "doSomething" - ), - operation: 0, - }; +export const mockTransaction = async (): Promise => { + return { + to: await getMockContract().getAddress(), + value: 0n, + // eslint-disable-next-line camelcase + data: MockContract__factory.createInterface().encodeFunctionData('doSomething'), + operation: 0, }; +}; -export const mockRevertTransaction = - async (): Promise => { - return { - to: await getMockContract().getAddress(), - value: 0n, - // eslint-disable-next-line camelcase - data: MockContract__factory.createInterface().encodeFunctionData( - "revertSomething" - ), - operation: 0, - }; +export const mockRevertTransaction = async (): Promise => { + return { + to: await getMockContract().getAddress(), + value: 0n, + // eslint-disable-next-line camelcase + data: MockContract__factory.createInterface().encodeFunctionData('revertSomething'), + operation: 0, }; +}; export const executeSafeTransaction = async ({ safe, @@ -228,7 +217,7 @@ export const executeSafeTransaction = async ({ }); const sigs = await Promise.all( - signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx)) + signers.map(async signer => safeSignTypedData(signer, safe, safeTx)), ); const tx = await safe.execTransaction( @@ -241,7 +230,7 @@ export const executeSafeTransaction = async ({ safeTx.gasPrice, safeTx.gasToken, safeTx.refundReceiver, - buildSignatureBytes(sigs) + buildSignatureBytes(sigs), ); return tx; @@ -252,22 +241,21 @@ export const getHatAccount = async ( erc6551RegistryImplementation: ERC6551Registry, mockHatsAccountImplementationAddress: string, mockHatsAddress: string, - signer?: ethers.Signer + signer?: ethers.Signer, ) => { - const salt = - "0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072"; + const salt = '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072'; const hatAccountAddress = await erc6551RegistryImplementation.account( mockHatsAccountImplementationAddress, salt, await hre.getChainId(), mockHatsAddress, - hatId + hatId, ); const hatAccount = MockHatsAccount__factory.connect( hatAccountAddress, - signer ?? hre.ethers.provider + signer ?? hre.ethers.provider, ); return hatAccount; diff --git a/test/time.ts b/test/time.ts index ca1c63a6..6c520709 100644 --- a/test/time.ts +++ b/test/time.ts @@ -1,4 +1,8 @@ -import hre from "hardhat"; +import hre from 'hardhat'; + +const advanceBlock = async () => { + await hre.ethers.provider.send('evm_mine', []); +}; const advanceBlocks = async (blockCount: number) => { for (let i = 0; i < blockCount; i++) { @@ -6,10 +10,6 @@ const advanceBlocks = async (blockCount: number) => { } }; -const advanceBlock = async () => { - await hre.ethers.provider.send("evm_mine", []); -}; - const defaultExport = { advanceBlocks, advanceBlock, From 3cc64fb0bf410d5b01a1d283ff992f427ce4af20 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 22 Oct 2024 11:15:28 -0400 Subject: [PATCH 109/206] Add a github action for linting and prettying --- .github/workflows/code-syntax.yml | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/code-syntax.yml diff --git a/.github/workflows/code-syntax.yml b/.github/workflows/code-syntax.yml new file mode 100644 index 00000000..e70a1ced --- /dev/null +++ b/.github/workflows/code-syntax.yml @@ -0,0 +1,37 @@ +name: Code Syntax +on: + push: + branches: + - develop + pull_request: +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up node + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + - name: Install dependencies + run: npm ci + - name: Compile contracts + run: npm run compile + - name: Run linter + run: npm run lint:check + pretty: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up node + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + - name: Install dependencies + run: npm ci + - name: Compile contracts + run: npm run compile + - name: Run prettier + run: npm run pretty:check From 1682d0178c430fabf6b2708251699a54b3c28b70 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 22 Oct 2024 12:37:30 -0400 Subject: [PATCH 110/206] Lint and pretty --- deploy/core/019_deploy_DecentHats.ts | 8 +- .../core/020_deploy_DecentAutonomousAdmin.ts | 8 +- test/DecentAutonomousAdmin.test.ts | 88 +-- test/DecentHats.test.ts | 526 +++++++++--------- 4 files changed, 314 insertions(+), 316 deletions(-) diff --git a/deploy/core/019_deploy_DecentHats.ts b/deploy/core/019_deploy_DecentHats.ts index a372d413..6f48e56d 100644 --- a/deploy/core/019_deploy_DecentHats.ts +++ b/deploy/core/019_deploy_DecentHats.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentHats"); + await deployNonUpgradeable(hre, 'DecentHats'); }; export default func; diff --git a/deploy/core/020_deploy_DecentAutonomousAdmin.ts b/deploy/core/020_deploy_DecentAutonomousAdmin.ts index f1adb696..a04d62d7 100644 --- a/deploy/core/020_deploy_DecentAutonomousAdmin.ts +++ b/deploy/core/020_deploy_DecentAutonomousAdmin.ts @@ -1,9 +1,9 @@ -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { DeployFunction } from "hardhat-deploy/types"; -import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, "DecentAutonomousAdmin"); + await deployNonUpgradeable(hre, 'DecentAutonomousAdmin'); }; export default func; diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index c9d9093f..fa4a2c49 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -1,3 +1,6 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre from 'hardhat'; import { DecentAutonomousAdmin, DecentAutonomousAdmin__factory, @@ -5,102 +8,99 @@ import { MockHatsAutoAdmin__factory, MockHatsElectionEligibility, MockHatsElectionEligibility__factory, -} from "../typechain-types" -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" -import { expect } from "chai" -import hre from "hardhat" +} from '../typechain-types'; -describe("DecentAutonomousAdminHat", function () { +describe('DecentAutonomousAdminHat', function () { // Signer accounts - let deployer: SignerWithAddress - let currentWearer: SignerWithAddress - let randomUser: SignerWithAddress - let nominatedWearer: SignerWithAddress + let deployer: SignerWithAddress; + let currentWearer: SignerWithAddress; + let randomUser: SignerWithAddress; + let nominatedWearer: SignerWithAddress; // Contract instances - let hatsProtocol: MockHatsAutoAdmin - let hatsElectionModule: MockHatsElectionEligibility - let adminHat: DecentAutonomousAdmin + let hatsProtocol: MockHatsAutoAdmin; + let hatsElectionModule: MockHatsElectionEligibility; + let adminHat: DecentAutonomousAdmin; // Variables - let userHatId: bigint + let userHatId: bigint; beforeEach(async function () { // Get signers - ;[deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners() + [deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners(); // Deploy MockHatsAutoAdmin (Mock Hats Protocol) - hatsProtocol = await new MockHatsAutoAdmin__factory(deployer).deploy() + hatsProtocol = await new MockHatsAutoAdmin__factory(deployer).deploy(); // Deploy MockHatsElectionEligibility (Eligibility Module) - hatsElectionModule = await new MockHatsElectionEligibility__factory(deployer).deploy() + hatsElectionModule = await new MockHatsElectionEligibility__factory(deployer).deploy(); // Create Admin Hat const createAdminTx = await hatsProtocol.createHat( await hatsProtocol.getAddress(), // Admin address (self-administered) - "Details", // Hat details + 'Details', // Hat details 100, // Max supply hre.ethers.ZeroAddress, // Eligibility module (none) hre.ethers.ZeroAddress, // Toggle module (none) true, // Is mutable - "imageURI" // Image URI - ) - const createAdminTxReceipt = await createAdminTx.wait() - const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0] + 'imageURI', // Image URI + ); + const createAdminTxReceipt = await createAdminTx.wait(); + const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0]; // Deploy DecentAutonomousAdminHat contract with the admin hat ID - adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy() - const adminHatAddress = await adminHat.getAddress() + adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy(); + const adminHatAddress = await adminHat.getAddress(); // Mint the admin hat to adminHatWearer - await hatsProtocol.mintHat(adminHatId, adminHatAddress) + await hatsProtocol.mintHat(adminHatId, adminHatAddress); // Create User Hat under the admin hat const createUserTx = await hatsProtocol.createHat( adminHatAddress, // Admin address (adminHat contract) - "Details", // Hat details + 'Details', // Hat details 100, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) hre.ethers.ZeroAddress, // Toggle module (none) false, // Is mutable - "imageURI" // Image URI - ) + 'imageURI', // Image URI + ); - const createUserTxReceipt = await createUserTx.wait() - userHatId = createUserTxReceipt?.toJSON().logs[0].args[0] + const createUserTxReceipt = await createUserTx.wait(); + userHatId = createUserTxReceipt?.toJSON().logs[0].args[0]; // Mint the user hat to currentWearer - await hatsProtocol.mintHat(userHatId, await currentWearer.getAddress()) - }) + await hatsProtocol.mintHat(userHatId, await currentWearer.getAddress()); + }); - describe("triggerStartNextTerm", function () { - it("should correctly validate current wearer and transfer", async function () { + describe('triggerStartNextTerm', function () { + it('should correctly validate current wearer and transfer', async function () { const args = { currentWearer: currentWearer.address, userHatProtocol: await hatsProtocol.getAddress(), userHatId: userHatId, nominatedWearer: nominatedWearer.address, sablierStreamInfo: [], // No Sablier stream info for this test - } + }; // Call triggerStartNextTerm on the adminHat contract - await adminHat.triggerStartNextTerm(args) + await adminHat.triggerStartNextTerm(args); // Verify the hat is now worn by the nominated wearer - expect(await hatsProtocol.isWearerOfHat(nominatedWearer.address, userHatId)).to.be.true - }) - it("should correctly invalidate random address as current wearer", async function () { + expect((await hatsProtocol.isWearerOfHat(nominatedWearer.address, userHatId)) === true); + }); + it('should correctly invalidate random address as current wearer', async function () { const args = { currentWearer: randomUser.address, userHatProtocol: await hatsProtocol.getAddress(), userHatId: userHatId, nominatedWearer: nominatedWearer.address, sablierStreamInfo: [], // No Sablier stream info for this test - } + }; // Verify the hat is now worn by the current wearer await expect(adminHat.connect(randomUser).triggerStartNextTerm(args)).to.be.revertedWith( - "Not current wearer" - ) - }) - }) -}) + 'Not current wearer', + ); + }); + }); +}); diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index e3aa14f2..8063981a 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -1,3 +1,6 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre, { ethers } from 'hardhat'; import { GnosisSafeL2, GnosisSafeL2__factory, @@ -21,20 +24,15 @@ import { ModuleProxyFactory, DecentAutonomousAdmin__factory, DecentAutonomousAdmin, -} from "../typechain-types" +} from '../typechain-types'; -import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers" -import { expect } from "chai" -import { ethers, keccak256, solidityPackedKeccak256, toUtf8Bytes } from "ethers" -import hre from "hardhat" - -import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from "./GlobalSafeDeployments.test" +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; import { buildSafeTransaction, buildSignatureBytes, predictGnosisSafeAddress, safeSignTypedData, -} from "./helpers" +} from './helpers'; const executeSafeTransaction = async ({ safe, @@ -42,20 +40,20 @@ const executeSafeTransaction = async ({ transactionData, signers, }: { - safe: GnosisSafeL2 - to: string - transactionData: string - signers: SignerWithAddress[] + safe: GnosisSafeL2; + to: string; + transactionData: string; + signers: SignerWithAddress[]; }) => { const safeTx = buildSafeTransaction({ to, data: transactionData, nonce: await safe.nonce(), - }) + }); const sigs = await Promise.all( - signers.map(async (signer) => await safeSignTypedData(signer, safe, safeTx)) - ) + signers.map(async signer => safeSignTypedData(signer, safe, safeTx)), + ); const tx = await safe.execTransaction( safeTx.to, @@ -67,71 +65,71 @@ const executeSafeTransaction = async ({ safeTx.gasPrice, safeTx.gasToken, safeTx.refundReceiver, - buildSignatureBytes(sigs) - ) + buildSignatureBytes(sigs), + ); - return tx -} + return tx; +}; -describe("DecentHats", () => { - let dao: SignerWithAddress +describe('DecentHats', () => { + let dao: SignerWithAddress; - let mockHats: MockHats - let mockHatsAddress: string + let mockHats: MockHats; + let mockHatsAddress: string; - let keyValuePairs: KeyValuePairs - let gnosisSafe: GnosisSafeL2 + let keyValuePairs: KeyValuePairs; + let gnosisSafe: GnosisSafeL2; - let decentHats: DecentHats - let decentHatsAddress: string + let decentHats: DecentHats; + let decentHatsAddress: string; - let gnosisSafeAddress: string - let erc6551Registry: ERC6551Registry + let gnosisSafeAddress: string; + let erc6551Registry: ERC6551Registry; - let mockHatsAccountImplementation: MockHatsAccount - let mockHatsAccountImplementationAddress: string + let mockHatsAccountImplementation: MockHatsAccount; + let mockHatsAccountImplementationAddress: string; - let mockSablier: MockSablierV2LockupLinear - let mockSablierAddress: string + let mockSablier: MockSablierV2LockupLinear; + let mockSablierAddress: string; - let mockERC20: MockERC20 - let mockERC20Address: string + let mockERC20: MockERC20; + let mockERC20Address: string; - let mockHatsElectionEligibilityImplementationAddress: string - let mockHatsModuleFactoryAddress: string + let mockHatsElectionEligibilityImplementationAddress: string; + let mockHatsModuleFactoryAddress: string; - let moduleProxyFactory: ModuleProxyFactory - let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin + let moduleProxyFactory: ModuleProxyFactory; + let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; beforeEach(async () => { - const signers = await hre.ethers.getSigners() - const [deployer] = signers - ;[, dao] = signers + const signers = await hre.ethers.getSigners(); + const [deployer] = signers; + [, dao] = signers; - mockHats = await new MockHats__factory(deployer).deploy() - mockHatsAddress = await mockHats.getAddress() + mockHats = await new MockHats__factory(deployer).deploy(); + mockHatsAddress = await mockHats.getAddress(); const mockHatsElectionEligibilityImplementation = - await new MockHatsElectionEligibility__factory(deployer).deploy() + await new MockHatsElectionEligibility__factory(deployer).deploy(); mockHatsElectionEligibilityImplementationAddress = - await mockHatsElectionEligibilityImplementation.getAddress() - const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy() - mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress() - keyValuePairs = await new KeyValuePairs__factory(deployer).deploy() - erc6551Registry = await new ERC6551Registry__factory(deployer).deploy() - mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy() - mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress() - decentHats = await new DecentHats__factory(deployer).deploy() - decentHatsAddress = await decentHats.getAddress() - - moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy() - decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy() - - const gnosisSafeProxyFactory = getGnosisSafeProxyFactory() - const gnosisSafeL2Singleton = getGnosisSafeL2Singleton() - const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress() + await mockHatsElectionEligibilityImplementation.getAddress(); + const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); + mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); + decentHats = await new DecentHats__factory(deployer).deploy(); + decentHatsAddress = await decentHats.getAddress(); + + moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( - "setup", + 'setup', [ [dao.address], 1, @@ -141,83 +139,83 @@ describe("DecentHats", () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ] - ) + ], + ); - const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString("hex")}`) + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); const predictedGnosisSafeAddress = await predictGnosisSafeAddress( createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory - ) - gnosisSafeAddress = predictedGnosisSafeAddress + gnosisSafeProxyFactory, + ); + gnosisSafeAddress = predictedGnosisSafeAddress; await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, - saltNum - ) + saltNum, + ); - gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer) + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy() - mockSablierAddress = await mockSablier.getAddress() + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockSablierAddress = await mockSablier.getAddress(); - mockERC20 = await new MockERC20__factory(deployer).deploy("MockERC20", "MCK") - mockERC20Address = await mockERC20.getAddress() + mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); + mockERC20Address = await mockERC20.getAddress(); - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther("1000000")) - }) + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); + }); - describe("DecentHats as a Module", () => { - let enableModuleTx: ethers.ContractTransactionResponse + describe('DecentHats as a Module', () => { + let enableModuleTx: ethers.ContractTransactionResponse; beforeEach(async () => { enableModuleTx = await executeSafeTransaction({ safe: gnosisSafe, to: gnosisSafeAddress, transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( - "enableModule", - [decentHatsAddress] + 'enableModule', + [decentHatsAddress], ), signers: [dao], - }) - }) + }); + }); - it("Emits an ExecutionSuccess event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "ExecutionSuccess") - }) + it('Emits an ExecutionSuccess event', async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); - it("Emits an EnabledModule event", async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, "EnabledModule").withArgs(decentHatsAddress) - }) + it('Emits an EnabledModule event', async () => { + await expect(enableModuleTx).to.emit(gnosisSafe, 'EnabledModule').withArgs(decentHatsAddress); + }); - describe("Creating a new Top Hat and Tree", () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse + describe('Creating a new Top Hat and Tree', () => { + let createAndDeclareTreeTx: ethers.ContractTransactionResponse; beforeEach(async () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, transactionData: DecentHats__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", + 'createAndDeclareTree', [ { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", + topHatDetails: '', + topHatImageURI: '', decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -232,8 +230,8 @@ describe("DecentHats", () => { hats: [ { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -247,8 +245,8 @@ describe("DecentHats", () => { }, { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -265,52 +263,52 @@ describe("DecentHats", () => { hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, - ] + ], ), signers: [dao], - }) - }) + }); + }); - it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") - }) + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress) - }) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); - it("Emits some hatsTreeId ValueUpdated events", async () => { + it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) - .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0") - }) + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '0'); + }); - describe("Multiple calls", () => { - let createAndDeclareTreeTx2: ethers.ContractTransactionResponse + describe('Multiple calls', () => { + let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; beforeEach(async () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, transactionData: DecentHats__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", + 'createAndDeclareTree', [ { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", + topHatDetails: '', + topHatImageURI: '', decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -327,35 +325,35 @@ describe("DecentHats", () => { hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, - ] + ], ), signers: [dao], - }) - }) + }); + }); - it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, "ExecutionSuccess") - }) + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx2) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress) - }) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); - it("Creates Top Hats with sequential IDs", async () => { + it('Creates Top Hats with sequential IDs', async () => { await expect(createAndDeclareTreeTx2) - .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "4") - }) - }) + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '4'); + }); + }); - describe("Creating Hats Accounts", () => { - let salt: string + describe('Creating Hats Accounts', () => { + let salt: string; beforeEach(async () => { - salt = await decentHats.SALT() - }) + salt = await decentHats.SALT(); + }); const getHatAccount = async (hatId: bigint) => { const hatAccountAddress = await erc6551Registry.account( @@ -363,55 +361,55 @@ describe("DecentHats", () => { salt, await hre.getChainId(), mockHatsAddress, - hatId - ) + hatId, + ); const hatAccount = MockHatsAccount__factory.connect( hatAccountAddress, - hre.ethers.provider - ) + hre.ethers.provider, + ); - return hatAccount - } + return hatAccount; + }; - it("Generates the correct Addresses for the current Hats", async () => { - const currentCount = await mockHats.count() + it('Generates the correct Addresses for the current Hats', async () => { + const currentCount = await mockHats.count(); for (let i = 0n; i < currentCount; i++) { - const topHatAccount = await getHatAccount(i) - expect(await topHatAccount.tokenId()).eq(i) - expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress) + const topHatAccount = await getHatAccount(i); + expect(await topHatAccount.tokenId()).eq(i); + expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); } - }) - }) - }) + }); + }); + }); - describe("Creating a new Top Hat and Tree with Sablier Streams", () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse - let currentBlockTimestamp: number + describe('Creating a new Top Hat and Tree with Sablier Streams', () => { + let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, transactionData: DecentHats__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", + 'createAndDeclareTree', [ { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", + topHatDetails: '', + topHatImageURI: '', decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -426,15 +424,15 @@ describe("DecentHats", () => { hats: [ { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [ { sablier: mockSablierAddress, sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), + totalAmount: ethers.parseEther('100'), asset: mockERC20Address, cancelable: true, transferable: false, @@ -456,8 +454,8 @@ describe("DecentHats", () => { }, { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -474,86 +472,86 @@ describe("DecentHats", () => { hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, - ] + ], ), signers: [dao], - }) - }) + }); + }); - it("Emits an ExecutionSuccess event", async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, "ExecutionSuccess") - }) + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); - it("Emits an ExecutionFromModuleSuccess event", async () => { + it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) - .to.emit(gnosisSafe, "ExecutionFromModuleSuccess") - .withArgs(decentHatsAddress) - }) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); - it("Emits some hatsTreeId ValueUpdated events", async () => { + it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) - .to.emit(keyValuePairs, "ValueUpdated") - .withArgs(gnosisSafeAddress, "topHatId", "0") - }) + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '0'); + }); - it("Creates a Sablier stream for the hat with stream parameters", async () => { + it('Creates a Sablier stream for the hat with stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ) - expect(streamCreatedEvents.length).to.equal(1) + mockSablier.filters.StreamCreated(), + ); + expect(streamCreatedEvents.length).to.equal(1); - const event = streamCreatedEvents[0] - expect(event.args.sender).to.equal(gnosisSafeAddress) - expect(event.args.recipient).to.not.equal(ethers.ZeroAddress) - expect(event.args.totalAmount).to.equal(ethers.parseEther("100")) - }) + const event = streamCreatedEvents[0]; + expect(event.args.sender).to.equal(gnosisSafeAddress); + expect(event.args.recipient).to.not.equal(ethers.ZeroAddress); + expect(event.args.totalAmount).to.equal(ethers.parseEther('100')); + }); - it("Does not create a Sablier stream for hats without stream parameters", async () => { + it('Does not create a Sablier stream for hats without stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ) - expect(streamCreatedEvents.length).to.equal(1) // Only one stream should be created - }) + mockSablier.filters.StreamCreated(), + ); + expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created + }); - it("Creates a Sablier stream with correct timestamps", async () => { + it('Creates a Sablier stream with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ) - expect(streamCreatedEvents.length).to.equal(1) + mockSablier.filters.StreamCreated(), + ); + expect(streamCreatedEvents.length).to.equal(1); - const streamId = streamCreatedEvents[0].args.streamId - const stream = await mockSablier.getStream(streamId) + const streamId = streamCreatedEvents[0].args.streamId; + const stream = await mockSablier.getStream(streamId); - expect(stream.startTime).to.equal(currentBlockTimestamp) - expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000) - }) - }) + expect(stream.startTime).to.equal(currentBlockTimestamp); + expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000); + }); + }); - describe("Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat", () => { - let currentBlockTimestamp: number + describe('Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat', () => { + let currentBlockTimestamp: number; beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock("latest"))!.timestamp + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, transactionData: DecentHats__factory.createInterface().encodeFunctionData( - "createAndDeclareTree", + 'createAndDeclareTree', [ { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: "", - topHatImageURI: "", + topHatDetails: '', + topHatImageURI: '', decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], @@ -568,15 +566,15 @@ describe("DecentHats", () => { hats: [ { maxSupply: 1, - details: "", - imageURI: "", + details: '', + imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [ { sablier: mockSablierAddress, sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("100"), + totalAmount: ethers.parseEther('100'), asset: mockERC20Address, cancelable: true, transferable: false, @@ -590,7 +588,7 @@ describe("DecentHats", () => { { sablier: mockSablierAddress, sender: gnosisSafeAddress, - totalAmount: ethers.parseEther("50"), + totalAmount: ethers.parseEther('50'), asset: mockERC20Address, cancelable: false, transferable: true, @@ -615,58 +613,58 @@ describe("DecentHats", () => { hatsElectionEligibilityImplementation: mockHatsElectionEligibilityImplementationAddress, }, - ] + ], ), signers: [dao], - }) - }) + }); + }); - it("Creates multiple Sablier streams for a single hat", async () => { + it('Creates multiple Sablier streams for a single hat', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ) - expect(streamCreatedEvents.length).to.equal(2) - - const event1 = streamCreatedEvents[0] - expect(event1.args.sender).to.equal(gnosisSafeAddress) - expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress) - expect(event1.args.totalAmount).to.equal(ethers.parseEther("100")) - - const event2 = streamCreatedEvents[1] - expect(event2.args.sender).to.equal(gnosisSafeAddress) - expect(event2.args.recipient).to.equal(event1.args.recipient) - expect(event2.args.totalAmount).to.equal(ethers.parseEther("50")) - }) - - it("Creates streams with correct parameters", async () => { + mockSablier.filters.StreamCreated(), + ); + expect(streamCreatedEvents.length).to.equal(2); + + const event1 = streamCreatedEvents[0]; + expect(event1.args.sender).to.equal(gnosisSafeAddress); + expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress); + expect(event1.args.totalAmount).to.equal(ethers.parseEther('100')); + + const event2 = streamCreatedEvents[1]; + expect(event2.args.sender).to.equal(gnosisSafeAddress); + expect(event2.args.recipient).to.equal(event1.args.recipient); + expect(event2.args.totalAmount).to.equal(ethers.parseEther('50')); + }); + + it('Creates streams with correct parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ) + mockSablier.filters.StreamCreated(), + ); - const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) - expect(stream1.cancelable).to.be.true - expect(stream1.transferable).to.be.false - expect(stream1.endTime - stream1.startTime).to.equal(2592000) + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); + expect(stream1.cancelable === true); + expect(stream1.transferable === false); + expect(stream1.endTime - stream1.startTime).to.equal(2592000); - const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) - expect(stream2.cancelable).to.be.false - expect(stream2.transferable).to.be.true - expect(stream2.endTime - stream2.startTime).to.equal(1296000) - }) + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); + expect(stream2.cancelable === false); + expect(stream2.transferable === true); + expect(stream2.endTime - stream2.startTime).to.equal(1296000); + }); - it("Creates streams with correct timestamps", async () => { + it('Creates streams with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() - ) - - const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId) - expect(stream1.startTime).to.equal(currentBlockTimestamp) - expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000) - - const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId) - expect(stream2.startTime).to.equal(currentBlockTimestamp) - expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000) - }) - }) - }) -}) + mockSablier.filters.StreamCreated(), + ); + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); + expect(stream1.startTime).to.equal(currentBlockTimestamp); + expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); + + const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); + expect(stream2.startTime).to.equal(currentBlockTimestamp); + expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); + }); + }); + }); +}); From e782284140a928400e9c46fca74dde76b6c505a0 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 22 Oct 2024 15:53:31 -0400 Subject: [PATCH 111/206] Add default overrides for solidity files --- .prettierrc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.prettierrc b/.prettierrc index 90a9a138..937339c8 100644 --- a/.prettierrc +++ b/.prettierrc @@ -6,5 +6,18 @@ "singleQuote": true, "semi": true, "arrowParens": "avoid", - "singleAttributePerLine": true + "singleAttributePerLine": true, + "overrides": [ + { + "files": "*.sol", + "options": { + "printWidth": 80, + "tabWidth": 4, + "useTabs": false, + "singleQuote": false, + "bracketSpacing": false, + "explicitTypes": "preserve" + } + } + ] } From faffebfaf6b4e07aa5e93148b741ef5b2d1fc68b Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:49:04 -0400 Subject: [PATCH 112/206] remove unused structand unsued comment area --- contracts/DecentAutonomousAdmin.sol | 4 ---- contracts/interfaces/IDecentAutonomousAdmin.sol | 5 ----- 2 files changed, 9 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 7d0fc5df..9a18997c 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -54,8 +54,4 @@ contract DecentAutonomousAdmin is interfaceId == type(IDecentAutonomousAdmin).interfaceId || super.supportsInterface(interfaceId); } - - // ////////////////////////////////////////////////////////////// - // Internal Functions - // ////////////////////////////////////////////////////////////// } diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentAutonomousAdmin.sol index ae4a7e34..2bcc99b0 100644 --- a/contracts/interfaces/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/IDecentAutonomousAdmin.sol @@ -5,11 +5,6 @@ import {IHats} from "./hats/full/IHats.sol"; import {ISablierV2Lockup} from "./sablier/full/ISablierV2Lockup.sol"; interface IDecentAutonomousAdmin { - struct SablierStreamInfo { - uint256 streamId; - ISablierV2Lockup sablierV2Lockup; - } - struct TriggerStartArgs { address currentWearer; IHats userHatProtocol; From 6e63069babe92754d446d92d01bd8d905cba50fa Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:24:19 -0400 Subject: [PATCH 113/206] remove unneeded conditionals --- contracts/DecentHats.sol | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index fc73aa33..b1a43338 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -224,9 +224,7 @@ contract DecentHats { hatId ); - if (hat.wearer != address(0)) { - hatsProtocol.mintHat(hatId, hat.wearer); - } + hatsProtocol.mintHat(hatId, hat.wearer); for (uint256 i = 0; i < hat.sablierParams.length; ) { SablierStreamParams memory sablierParams = hat.sablierParams[i]; @@ -292,9 +290,7 @@ contract DecentHats { hat.termedParams[0].nominatedWearers ); - if (hat.wearer != address(0)) { - hatsProtocol.mintHat(hatId, hat.wearer); - } + hatsProtocol.mintHat(hatId, hat.termedParams[0].nominatedWearers[0]); for (uint256 i = 0; i < hat.sablierParams.length; ) { SablierStreamParams memory sablierParams = hat.sablierParams[i]; From c175538527c80dbb4e62dd2b4fee5dd8ac61e9fe Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:24:38 -0400 Subject: [PATCH 114/206] add requires to check term param length and nominees length --- contracts/DecentHats.sol | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index b1a43338..f7d7a6d9 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -277,6 +277,14 @@ contract DecentHats { uint256 adminHatId, Hat calldata hat ) internal { + require( + hat.termedParams.length == 1, + "DecentHats: termedParams length must be 1" + ); + require( + hat.termedParams[0].nominatedWearers.length == 1, + "DecentHats: nominatedWearers length must be 1" + ); uint256 hatId = _createHat( hatsProtocol, adminHatId, @@ -310,7 +318,7 @@ contract DecentHats { LockupLinear.CreateWithTimestamps memory params = LockupLinear .CreateWithTimestamps({ sender: sablierParams.sender, - recipient: hat.wearer, + recipient: hat.termedParams[0].nominatedWearers[0], totalAmount: sablierParams.totalAmount, asset: IERC20(sablierParams.asset), cancelable: sablierParams.cancelable, From 1563a93898414ffd3bcdf89465246b43c3fa8ae5 Mon Sep 17 00:00:00 2001 From: Kellar Date: Thu, 24 Oct 2024 17:21:34 +0100 Subject: [PATCH 115/206] Add `createRoleHat` --- contracts/DecentHats_0_1_0.sol | 27 ++- deployments/sepolia/DecentHats_0_1_0.json | 192 ++++++++++++++++-- .../868499c9bf8e01dcdf8b61017b8261aa.json | 59 ++++++ test/DecentHats_0_1_0.test.ts | 129 ++++++++++-- 4 files changed, 375 insertions(+), 32 deletions(-) create mode 100644 deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index a0d9a7bd..a870fd4b 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -49,7 +49,7 @@ contract DecentHats_0_1_0 { 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; } - function updateKeyValuePairs( + function declareSafeHatTree( address _keyValuePairs, uint256 topHatId ) internal { @@ -195,6 +195,29 @@ contract DecentHats_0_1_0 { } } + function createRoleHat( + IHats hatsProtocol, + uint256 adminHatId, + Hat calldata hat, + uint256 topHatId, + address topHatAccount, + IERC6551Registry registry, + address hatsAccountImplementation, + bytes32 salt + ) public returns (uint256 hatId, address accountAddress) { + (hatId, accountAddress) = createHatAndAccountAndMintAndStreams( + hatsProtocol, + adminHatId, + hat, + topHatAccount, + registry, + hatsAccountImplementation, + salt + ); + + hatsProtocol.transferHat(topHatId, address(this), msg.sender); + } + function createAndDeclareTree(CreateTreeParams calldata params) public { bytes32 salt = getSalt(); @@ -207,7 +230,7 @@ contract DecentHats_0_1_0 { salt ); - updateKeyValuePairs(params.keyValuePairs, topHatId); + declareSafeHatTree(params.keyValuePairs, topHatId); (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams( params.hatsProtocol, diff --git a/deployments/sepolia/DecentHats_0_1_0.json b/deployments/sepolia/DecentHats_0_1_0.json index d0d70862..dedfc260 100644 --- a/deployments/sepolia/DecentHats_0_1_0.json +++ b/deployments/sepolia/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x577FcfB0655f24809345E951f188b1929A961E42", + "address": "0xB1ba8caa9a65f4Bf53a5D1A1bD5514dFc9bB7E35", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,28 +451,28 @@ "type": "function" } ], - "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", + "transactionHash": "0x120ac49ebb96472eb64f1252708ce2409a3e59965dc6e562da7e3bb8c4d9dae8", "receipt": { "to": null, - "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x577FcfB0655f24809345E951f188b1929A961E42", - "transactionIndex": 9, - "gasUsed": "1162443", + "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", + "contractAddress": "0xB1ba8caa9a65f4Bf53a5D1A1bD5514dFc9bB7E35", + "transactionIndex": 61, + "gasUsed": "1243967", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x614020dff98bee6b1b1949ba946f7f8d5b1054f3199eb499f979e82889712945", - "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", + "blockHash": "0xecaeebc43ae4b779fc8e01b4b2b9a95013daac4714041d0e67a8e65723b062e7", + "transactionHash": "0x120ac49ebb96472eb64f1252708ce2409a3e59965dc6e562da7e3bb8c4d9dae8", "logs": [], - "blockNumber": 6852403, - "cumulativeGasUsed": "1938170", + "blockNumber": 6936950, + "cumulativeGasUsed": "15576172", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 11, + "solcInputHash": "868499c9bf8e01dcdf8b61017b8261aa", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x58532ec529a100ab86d99edf81bbd2fd8a8c31a0cd69ec060a2da09ec5d2be9a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea264697066735822122048ef86ec0b25aed489e983eeea91e1834819fb066f709e998fda6ce0bf00349f64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea264697066735822122048ef86ec0b25aed489e983eeea91e1834819fb066f709e998fda6ce0bf00349f64736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json b/deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json new file mode 100644 index 00000000..8b9a1149 --- /dev/null +++ b/deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index d20a600c..b04bf8f6 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -76,7 +76,7 @@ describe('DecentHats_0_1_0', () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ], + ] ); const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); @@ -85,14 +85,14 @@ describe('DecentHats_0_1_0', () => { createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory, + gnosisSafeProxyFactory ); gnosisSafeAddress = predictedGnosisSafeAddress; await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, - saltNum, + saltNum ); gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); @@ -116,7 +116,7 @@ describe('DecentHats_0_1_0', () => { to: gnosisSafeAddress, transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( 'enableModule', - [decentHatsAddress], + [decentHatsAddress] ), signers: [dao], }); @@ -178,7 +178,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ], + ] ), signers: [dao], }); @@ -227,7 +227,7 @@ describe('DecentHats_0_1_0', () => { }, hats: [], }, - ], + ] ), signers: [dao], }); @@ -259,7 +259,7 @@ describe('DecentHats_0_1_0', () => { i, erc6551Registry, mockHatsAccountImplementationAddress, - mockHatsAddress, + mockHatsAddress ); expect(await topHatAccount.tokenId()).eq(i); @@ -331,7 +331,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ], + ] ), signers: [dao], }); @@ -355,7 +355,7 @@ describe('DecentHats_0_1_0', () => { it('Creates a Sablier stream for the hat with stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), + mockSablier.filters.StreamCreated() ); expect(streamCreatedEvents.length).to.equal(1); @@ -367,14 +367,14 @@ describe('DecentHats_0_1_0', () => { it('Does not create a Sablier stream for hats without stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), + mockSablier.filters.StreamCreated() ); expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created }); it('Creates a Sablier stream with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), + mockSablier.filters.StreamCreated() ); expect(streamCreatedEvents.length).to.equal(1); @@ -453,7 +453,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ], + ] ), signers: [dao], }); @@ -461,7 +461,7 @@ describe('DecentHats_0_1_0', () => { it('Creates multiple Sablier streams for a single hat', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), + mockSablier.filters.StreamCreated() ); expect(streamCreatedEvents.length).to.equal(2); @@ -478,7 +478,7 @@ describe('DecentHats_0_1_0', () => { it('Creates streams with correct parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), + mockSablier.filters.StreamCreated() ); const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); @@ -494,7 +494,7 @@ describe('DecentHats_0_1_0', () => { it('Creates streams with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), + mockSablier.filters.StreamCreated() ); const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); @@ -506,5 +506,104 @@ describe('DecentHats_0_1_0', () => { expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); }); }); + + describe('Creating a new hat on existing Tree', () => { + let createHatAndAccountAndMintAndStreamsTx: ethers.ContractTransactionResponse; + + beforeEach(async () => { + await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + hats: [ + { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + }, + ], + }, + ] + ), + signers: [dao], + }); + + const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + + createHatAndAccountAndMintAndStreamsTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + 'createRoleHat', + [ + mockHatsAddress, + 1, + { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: true, + wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + 0, + '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + await erc6551Registry.getAddress(), + mockHatsAccountImplementationAddress, + '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072', + ] + ), + signers: [dao], + }); + }); + + it('Emits an ExecutionSuccess event', async () => { + await expect(createHatAndAccountAndMintAndStreamsTx).to.emit( + gnosisSafe, + 'ExecutionSuccess' + ); + }); + + it('Emits an ExecutionFromModuleSuccess event', async () => { + await expect(createHatAndAccountAndMintAndStreamsTx) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); + }); }); }); From 2c353b66c92d87f0e41428cc0411fb18bc56586b Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 14:35:36 +0100 Subject: [PATCH 116/206] Add doc --- contracts/DecentHats_0_1_0.sol | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index a870fd4b..a44756ee 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -195,6 +195,20 @@ contract DecentHats_0_1_0 { } } + /** + * Creates a new role hat and any streams on it. + * + * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. + * In order for the module to be able to create hats on behalf of the Safe, the Safe must first + * transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * creating the role hat. + * + * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * + * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order + * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. + * See: https://github.com/decentdao/decent-interface/issues/2402 + */ function createRoleHat( IHats hatsProtocol, uint256 adminHatId, @@ -218,6 +232,17 @@ contract DecentHats_0_1_0 { hatsProtocol.transferHat(topHatId, address(this), msg.sender); } + /** + * For a safe without any roles previously created on it, this function should be called. It sets up the + * top hat and admin hat, as well as any other hats and their streams that are provided. + * + * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. + * + * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has + * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, + * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. + * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. + */ function createAndDeclareTree(CreateTreeParams calldata params) public { bytes32 salt = getSalt(); From 4b6f9944132f826fa60834033c6a307dbf148cc1 Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 14:40:25 +0100 Subject: [PATCH 117/206] Remove, revert sepolia deployment artifacts --- deployments/sepolia/DecentHats_0_1_0.json | 192 ++---------------- .../868499c9bf8e01dcdf8b61017b8261aa.json | 59 ------ 2 files changed, 15 insertions(+), 236 deletions(-) delete mode 100644 deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json diff --git a/deployments/sepolia/DecentHats_0_1_0.json b/deployments/sepolia/DecentHats_0_1_0.json index dedfc260..d0d70862 100644 --- a/deployments/sepolia/DecentHats_0_1_0.json +++ b/deployments/sepolia/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0xB1ba8caa9a65f4Bf53a5D1A1bD5514dFc9bB7E35", + "address": "0x577FcfB0655f24809345E951f188b1929A961E42", "abi": [ { "inputs": [], @@ -275,168 +275,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "adminHatId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "hat", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "topHatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "topHatAccount", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "createRoleHat", - "outputs": [ - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "accountAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "getSalt", @@ -451,28 +289,28 @@ "type": "function" } ], - "transactionHash": "0x120ac49ebb96472eb64f1252708ce2409a3e59965dc6e562da7e3bb8c4d9dae8", + "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", "receipt": { "to": null, - "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", - "contractAddress": "0xB1ba8caa9a65f4Bf53a5D1A1bD5514dFc9bB7E35", - "transactionIndex": 61, - "gasUsed": "1243967", + "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", + "contractAddress": "0x577FcfB0655f24809345E951f188b1929A961E42", + "transactionIndex": 9, + "gasUsed": "1162443", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xecaeebc43ae4b779fc8e01b4b2b9a95013daac4714041d0e67a8e65723b062e7", - "transactionHash": "0x120ac49ebb96472eb64f1252708ce2409a3e59965dc6e562da7e3bb8c4d9dae8", + "blockHash": "0x614020dff98bee6b1b1949ba946f7f8d5b1054f3199eb499f979e82889712945", + "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", "logs": [], - "blockNumber": 6936950, - "cumulativeGasUsed": "15576172", + "blockNumber": 6852403, + "cumulativeGasUsed": "1938170", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 11, - "solcInputHash": "868499c9bf8e01dcdf8b61017b8261aa", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x58532ec529a100ab86d99edf81bbd2fd8a8c31a0cd69ec060a2da09ec5d2be9a\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea264697066735822122048ef86ec0b25aed489e983eeea91e1834819fb066f709e998fda6ce0bf00349f64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea264697066735822122048ef86ec0b25aed489e983eeea91e1834819fb066f709e998fda6ce0bf00349f64736f6c63430008130033", + "numDeployments": 5, + "solcInputHash": "6ceb8d75a501322d052845dbe517017d", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json b/deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json deleted file mode 100644 index 8b9a1149..00000000 --- a/deployments/sepolia/solcInputs/868499c9bf8e01dcdf8b61017b8261aa.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" - }, - "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "contracts/DecentHats_0_1_0.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" - }, - "contracts/interfaces/hats/IHats.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" - }, - "contracts/interfaces/IERC6551Registry.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" - }, - "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" - }, - "contracts/interfaces/sablier/LockupLinear.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file From a9e6a474483ff711624c7b8e5d7166567db88d77 Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 15:05:51 +0100 Subject: [PATCH 118/206] update prettier --- .prettierrc | 1 + test/DecentHats_0_1_0.test.ts | 36 +++++++++++++++++------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.prettierrc b/.prettierrc index 937339c8..9b687cc7 100644 --- a/.prettierrc +++ b/.prettierrc @@ -7,6 +7,7 @@ "semi": true, "arrowParens": "avoid", "singleAttributePerLine": true, + "trailingComma": "all", "overrides": [ { "files": "*.sol", diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index b04bf8f6..6f1ef60d 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -76,7 +76,7 @@ describe('DecentHats_0_1_0', () => { hre.ethers.ZeroAddress, 0, hre.ethers.ZeroAddress, - ] + ], ); const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); @@ -85,14 +85,14 @@ describe('DecentHats_0_1_0', () => { createGnosisSetupCalldata, saltNum, gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory + gnosisSafeProxyFactory, ); gnosisSafeAddress = predictedGnosisSafeAddress; await gnosisSafeProxyFactory.createProxyWithNonce( gnosisSafeL2SingletonAddress, createGnosisSetupCalldata, - saltNum + saltNum, ); gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); @@ -116,7 +116,7 @@ describe('DecentHats_0_1_0', () => { to: gnosisSafeAddress, transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( 'enableModule', - [decentHatsAddress] + [decentHatsAddress], ), signers: [dao], }); @@ -178,7 +178,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ] + ], ), signers: [dao], }); @@ -227,7 +227,7 @@ describe('DecentHats_0_1_0', () => { }, hats: [], }, - ] + ], ), signers: [dao], }); @@ -259,7 +259,7 @@ describe('DecentHats_0_1_0', () => { i, erc6551Registry, mockHatsAccountImplementationAddress, - mockHatsAddress + mockHatsAddress, ); expect(await topHatAccount.tokenId()).eq(i); @@ -331,7 +331,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ] + ], ), signers: [dao], }); @@ -355,7 +355,7 @@ describe('DecentHats_0_1_0', () => { it('Creates a Sablier stream for the hat with stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(1); @@ -367,14 +367,14 @@ describe('DecentHats_0_1_0', () => { it('Does not create a Sablier stream for hats without stream parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created }); it('Creates a Sablier stream with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(1); @@ -453,7 +453,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ] + ], ), signers: [dao], }); @@ -461,7 +461,7 @@ describe('DecentHats_0_1_0', () => { it('Creates multiple Sablier streams for a single hat', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); expect(streamCreatedEvents.length).to.equal(2); @@ -478,7 +478,7 @@ describe('DecentHats_0_1_0', () => { it('Creates streams with correct parameters', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); @@ -494,7 +494,7 @@ describe('DecentHats_0_1_0', () => { it('Creates streams with correct timestamps', async () => { const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated() + mockSablier.filters.StreamCreated(), ); const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); @@ -543,7 +543,7 @@ describe('DecentHats_0_1_0', () => { }, ], }, - ] + ], ), signers: [dao], }); @@ -586,7 +586,7 @@ describe('DecentHats_0_1_0', () => { await erc6551Registry.getAddress(), mockHatsAccountImplementationAddress, '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072', - ] + ], ), signers: [dao], }); @@ -595,7 +595,7 @@ describe('DecentHats_0_1_0', () => { it('Emits an ExecutionSuccess event', async () => { await expect(createHatAndAccountAndMintAndStreamsTx).to.emit( gnosisSafe, - 'ExecutionSuccess' + 'ExecutionSuccess', ); }); From 169724b4f5482996cf2ad54d9675b339899277c4 Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 15:15:14 +0100 Subject: [PATCH 119/206] deploy contracts --- deployments/base/DecentHats_0_1_0.json | 208 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/mainnet/DecentHats_0_1_0.json | 208 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/optimism/DecentHats_0_1_0.json | 208 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/polygon/DecentHats_0_1_0.json | 224 ++++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/sepolia/DecentHats_0_1_0.json | 210 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ 10 files changed, 1264 insertions(+), 89 deletions(-) create mode 100644 deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json diff --git a/deployments/base/DecentHats_0_1_0.json b/deployments/base/DecentHats_0_1_0.json index 6ecfc1b4..ec1bdb20 100644 --- a/deployments/base/DecentHats_0_1_0.json +++ b/deployments/base/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", + "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0x5d86a480602424ac02518917b0eb305225c80775da3569f318942c31ac8424b3", + "transactionHash": "0x5e1f773df67fb54ba7cf1b3b500c8bf99b45f2c4bc0442f53ffb9e2b42738a00", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", - "transactionIndex": 56, - "gasUsed": "1162443", + "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", + "transactionIndex": 67, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1eb0f75b3947cd2eacb086e5add97af2d11d11b47767445a9daf2cebc6589b07", - "transactionHash": "0x5d86a480602424ac02518917b0eb305225c80775da3569f318942c31ac8424b3", + "blockHash": "0x4972942095f87c4710d5794d86dd19283408255356cabe89217a00cf41239cf8", + "transactionHash": "0x5e1f773df67fb54ba7cf1b3b500c8bf99b45f2c4bc0442f53ffb9e2b42738a00", "logs": [], - "blockNumber": 20902423, - "cumulativeGasUsed": "8359038", + "blockNumber": 21538074, + "cumulativeGasUsed": "14620525", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/DecentHats_0_1_0.json b/deployments/mainnet/DecentHats_0_1_0.json index 616a515a..6f619b3f 100644 --- a/deployments/mainnet/DecentHats_0_1_0.json +++ b/deployments/mainnet/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x5843E6fa58163453A0A753a831E3BbdB2da06259", + "address": "0x3F852ac21185E62F322F8d0Ca680b06c077280D5", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0x45225faa4aac42f403a10912758bb375c1889ddf98627000370b20f840cc6365", + "transactionHash": "0x1a2b34ff7f671d4a727d06ad509eca16d699e76b87c36bc0996579b9e649272e", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x5843E6fa58163453A0A753a831E3BbdB2da06259", - "transactionIndex": 38, - "gasUsed": "1162443", + "contractAddress": "0x3F852ac21185E62F322F8d0Ca680b06c077280D5", + "transactionIndex": 9, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc9ec4b47f2e757a387beeebfc3a17c51f90b4a81df75af0eab0d5286f5637cfe", - "transactionHash": "0x45225faa4aac42f403a10912758bb375c1889ddf98627000370b20f840cc6365", + "blockHash": "0x9aac8241b655d66208a24411411b3f2b81bd4edda3d80847c6b1c46b8e71d85e", + "transactionHash": "0x1a2b34ff7f671d4a727d06ad509eca16d699e76b87c36bc0996579b9e649272e", "logs": [], - "blockNumber": 20937775, - "cumulativeGasUsed": "5113096", + "blockNumber": 21043134, + "cumulativeGasUsed": "2480225", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/DecentHats_0_1_0.json b/deployments/optimism/DecentHats_0_1_0.json index 905e0851..06cee265 100644 --- a/deployments/optimism/DecentHats_0_1_0.json +++ b/deployments/optimism/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", + "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0x838e49f34e0c5da270a3ee8945c11b664f1cc242cb6b3c794464795333813910", + "transactionHash": "0x57c929ca92770fd06f0a51d038d29bfbf8790582f290fefb712c9b5a867aee84", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", - "transactionIndex": 12, - "gasUsed": "1162443", + "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", + "transactionIndex": 24, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4673e4ee1835f9085310f9f34eb7da3086eba765920c7de3c35d4b6870f668c6", - "transactionHash": "0x838e49f34e0c5da270a3ee8945c11b664f1cc242cb6b3c794464795333813910", + "blockHash": "0x7b3f0fd56bbfa019a8edb17cd23803cc2fdb06712a35d74474c06b09828d73c6", + "transactionHash": "0x57c929ca92770fd06f0a51d038d29bfbf8790582f290fefb712c9b5a867aee84", "logs": [], - "blockNumber": 126497749, - "cumulativeGasUsed": "2827783", + "blockNumber": 127133402, + "cumulativeGasUsed": "7388287", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/DecentHats_0_1_0.json b/deployments/polygon/DecentHats_0_1_0.json index 430c2ee9..4f31841f 100644 --- a/deployments/polygon/DecentHats_0_1_0.json +++ b/deployments/polygon/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0xF45EAc866BAD509B0CD233869b61be8b0BC6dBd8", + "address": "0xD16368a8b709cBAfd47c480607a843144Bcd27Dc", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,52 +451,66 @@ "type": "function" } ], - "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", + "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xF45EAc866BAD509B0CD233869b61be8b0BC6dBd8", - "transactionIndex": 9, - "gasUsed": "1162443", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000100004000000000000000000200000000000000000000000000000000000000000000000100000", - "blockHash": "0x7d22d6e543e1e0df7018ad856b6b90ec9d58b64b8b0ffc66abc8ad4d4c2ac537", - "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", + "contractAddress": "0xD16368a8b709cBAfd47c480607a843144Bcd27Dc", + "transactionIndex": 40, + "gasUsed": "1243979", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000120004000000000000000000200000000000000000000000000000000000000000000000100000", + "blockHash": "0xd9e72f56a6a5a78cf740fa9f15bee4930ed50fcf55b112b8f6165202a874477c", + "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", "logs": [ { - "transactionIndex": 9, - "blockNumber": 62879901, - "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", + "transactionIndex": 40, + "blockNumber": 63474684, + "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x000000000000000000000000b5ca125166c1987a35edd550e16846fa1e1d9bb3", - "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" ], - "data": "0x00000000000000000000000000000000000000000000000001084f16858b800000000000000000000000000000000000000000000000000034103173616baf340000000000000000000000000000000000000000000339407dbafe9f1de83cf40000000000000000000000000000000000000000000000003307e25cdbe02f340000000000000000000000000000000000000000000339407ec34db5a373bcf4", - "logIndex": 91, - "blockHash": "0x7d22d6e543e1e0df7018ad856b6b90ec9d58b64b8b0ffc66abc8ad4d4c2ac537" + "data": "0x00000000000000000000000000000000000000000000000000bcc837b2df4d5a0000000000000000000000000000000000000000000000003307e25cd9ef8900000000000000000000000000000000000000000000000b962f1502731c562a88000000000000000000000000000000000000000000000000324b1a2527103ba6000000000000000000000000000000000000000000000b962fd1caaacf3577e2", + "logIndex": 247, + "blockHash": "0xd9e72f56a6a5a78cf740fa9f15bee4930ed50fcf55b112b8f6165202a874477c" } ], - "blockNumber": 62879901, - "cumulativeGasUsed": "3502682", + "blockNumber": 63474684, + "cumulativeGasUsed": "9341874", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/sepolia/DecentHats_0_1_0.json b/deployments/sepolia/DecentHats_0_1_0.json index d0d70862..fc9fee8b 100644 --- a/deployments/sepolia/DecentHats_0_1_0.json +++ b/deployments/sepolia/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x577FcfB0655f24809345E951f188b1929A961E42", + "address": "0x0bEe0a447e6A5bEA8CAA0d8559A681EE16d6caCE", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", + "transactionHash": "0xf40bd3ced4aeef501671b0cdb5b38737c085281f0b2147ac8e4aae18667fa1dd", "receipt": { "to": null, - "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x577FcfB0655f24809345E951f188b1929A961E42", - "transactionIndex": 9, - "gasUsed": "1162443", + "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", + "contractAddress": "0x0bEe0a447e6A5bEA8CAA0d8559A681EE16d6caCE", + "transactionIndex": 52, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x614020dff98bee6b1b1949ba946f7f8d5b1054f3199eb499f979e82889712945", - "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", + "blockHash": "0x348e807031247225bcd356c1719d5ef0ae8dec1556f477af9b569308deddf9f3", + "transactionHash": "0xf40bd3ced4aeef501671b0cdb5b38737c085281f0b2147ac8e4aae18667fa1dd", "logs": [], - "blockNumber": 6852403, - "cumulativeGasUsed": "1938170", + "blockNumber": 6943061, + "cumulativeGasUsed": "5696224", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file From a0e356c228a8cbe0815d0ca455f99d777ec8fcd7 Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 17:41:14 +0100 Subject: [PATCH 120/206] Update tests --- contracts/interfaces/hats/IHats.sol | 5 +++ contracts/mocks/MockHats.sol | 25 +++++++++++++-- test/DecentHats_0_1_0.test.ts | 48 ++++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index c460c46d..e78f6c61 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -39,4 +39,9 @@ interface IHats { ) external returns (bool success); function transferHat(uint256 _hatId, address _from, address _to) external; + + function isWearerOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isWearer); } diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index f5ac2ece..0eb011a0 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -5,14 +5,16 @@ import {IHats} from "../interfaces/hats/IHats.sol"; contract MockHats is IHats { uint256 public count = 0; + mapping(uint256 => address) hatWearers; function mintTopHat( - address, + address _target, string memory, string memory ) external returns (uint256 topHatId) { topHatId = count; count++; + hatWearers[topHatId] = _target; } function createHat( @@ -28,9 +30,26 @@ contract MockHats is IHats { count++; } - function mintHat(uint256, address) external pure returns (bool success) { + function mintHat( + uint256 hatId, + address wearer + ) external returns (bool success) { success = true; + hatWearers[hatId] = wearer; + } + + function transferHat(uint256 _hatId, address _from, address _to) external { + require( + hatWearers[_hatId] == _from, + "MockHats: Invalid current wearer" + ); + hatWearers[_hatId] = _to; } - function transferHat(uint256, address, address) external {} + function isWearerOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isWearer) { + isWearer = hatWearers[_hatId] == _user; + } } diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 6f1ef60d..1285352f 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -508,7 +508,8 @@ describe('DecentHats_0_1_0', () => { }); describe('Creating a new hat on existing Tree', () => { - let createHatAndAccountAndMintAndStreamsTx: ethers.ContractTransactionResponse; + let createRoleHatPromise: Promise; + const topHatId = 0; beforeEach(async () => { await executeSafeTransaction({ @@ -550,7 +551,7 @@ describe('DecentHats_0_1_0', () => { const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - createHatAndAccountAndMintAndStreamsTx = await executeSafeTransaction({ + createRoleHatPromise = executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( @@ -592,18 +593,51 @@ describe('DecentHats_0_1_0', () => { }); }); + it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { + await expect(createRoleHatPromise).to.be.reverted; + }); + it('Emits an ExecutionSuccess event', async () => { - await expect(createHatAndAccountAndMintAndStreamsTx).to.emit( - gnosisSafe, - 'ExecutionSuccess', - ); + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); }); it('Emits an ExecutionFromModuleSuccess event', async () => { - await expect(createHatAndAccountAndMintAndStreamsTx) + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await expect(await createRoleHatPromise) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentHatsAddress); }); + + it('Transfers the top hat back to the Safe', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + + const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); + expect(isModuleWearerOfTopHat).to.equal(true); + + await createRoleHatPromise; + + const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); + expect(isSafeWearerOfTopHat).to.equal(true); + }); + + it('Actually creates the new hat', async () => { + const hatsCountBeforeCreate = await mockHats.count(); + console.log({ hatsCountBeforeCreate }); + + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + + expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat + + await createRoleHatPromise; + + const newHatId = await mockHats.count(); + expect(newHatId).to.equal(3); + }); }); }); }); From 71561027934dc272d16aa2601959d28378de2fad Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 17:48:56 +0100 Subject: [PATCH 121/206] build bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 55e0d734..4c69e695 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.16", + "version": "1.2.17", "files": [ "publish", "contracts", From e314c7e992f98043d424716d35d6c7f4734e672b Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 17:54:11 +0100 Subject: [PATCH 122/206] Fix test --- test/DecentHats_0_1_0.test.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 1285352f..7ffb285e 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -533,16 +533,7 @@ describe('DecentHats_0_1_0', () => { wearer: ethers.ZeroAddress, sablierParams: [], }, - hats: [ - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], + hats: [], }, ], ), @@ -625,18 +616,16 @@ describe('DecentHats_0_1_0', () => { }); it('Actually creates the new hat', async () => { - const hatsCountBeforeCreate = await mockHats.count(); - console.log({ hatsCountBeforeCreate }); - // First transfer the top hat to the Safe await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + const hatsCountBeforeCreate = await mockHats.count(); expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat await createRoleHatPromise; const newHatId = await mockHats.count(); - expect(newHatId).to.equal(3); + expect(newHatId).to.equal(3); // + newly created hat }); }); }); From 3728ff6ae7db89a8afdc629953795957a5736984 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 25 Oct 2024 14:37:06 -0400 Subject: [PATCH 123/206] Bump version in package-lock --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d05df06..09c4854d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.16", + "version": "1.2.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.16", + "version": "1.2.17", "license": "MIT", "dependencies": { "@gnosis.pm/zodiac": "^1.1.4", From fe6a630e54b8e102f5a9d986ad193d288c9da6bb Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 25 Oct 2024 14:46:04 -0400 Subject: [PATCH 124/206] Revert change to IHats --- contracts/interfaces/hats/IHats.sol | 5 ----- 1 file changed, 5 deletions(-) diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index e78f6c61..c460c46d 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -39,9 +39,4 @@ interface IHats { ) external returns (bool success); function transferHat(uint256 _hatId, address _from, address _to) external; - - function isWearerOfHat( - address _user, - uint256 _hatId - ) external view returns (bool isWearer); } From 6e9e322726e328bfc852c93571effe5f0aad1cb8 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 12:50:08 -0400 Subject: [PATCH 125/206] update with public function to create new RoleHats --- contracts/DecentHats.sol | 50 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index f7d7a6d9..fc01f46d 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -64,6 +64,17 @@ contract DecentHats { /* ///////////////////////////////////////////////////////////////////////////// EXTERNAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ + /** + * For a safe without any roles previously created on it, this function should be called. It sets up the + * top hat and admin hat, as well as any other hats and their streams that are provided. + * + * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. + * + * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has + * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, + * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. + * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. + */ function createAndDeclareTree(CreateTreeParams calldata params) public { (uint256 topHatId, address topHatAccount) = _createTopHatAndAccount( params.hatsProtocol, @@ -73,7 +84,7 @@ contract DecentHats { params.hatsAccountImplementation ); - _updateKeyValuePairs(params.keyValuePairs, topHatId); + _declareSafeHatTree(params.keyValuePairs, topHatId); (uint256 adminHatId, ) = _createAdminHatAndAccount( params.hatsProtocol, @@ -121,11 +132,46 @@ contract DecentHats { params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); } + /** + * Creates a new role hat and any streams on it. + * + * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. + * In order for the module to be able to create hats on behalf of the Safe, the Safe must first + * transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * creating the role hat. + * + * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * + * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order + * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. + * See: https://github.com/decentdao/decent-interface/issues/2402 + */ + function createRoleHat( + IHats hatsProtocol, + IERC6551Registry registry, + address topHatAccount, + address hatsAccountImplementation, + uint256 adminHatId, + uint256 topHatId, + Hat calldata hat + ) public returns (uint256 hatId, address accountAddress) { + (hatId, accountAddress) = _createHatAndAccountAndMintAndStreams( + hatsProtocol, + registry, + topHatAccount, + hatsAccountImplementation, + adminHatId, + hat + ); + + hatsProtocol.transferHat(topHatId, address(this), msg.sender); + } + /* ///////////////////////////////////////////////////////////////////////////// INTERAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ - function _updateKeyValuePairs( + function _declareSafeHatTree( address _keyValuePairs, uint256 topHatId ) internal { From d0baf89bc7445a89f842aab8c17f9ee0900b5551 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 13:52:49 -0400 Subject: [PATCH 126/206] Add createTermRole external function - update params into structs and calldata --- contracts/DecentHats.sol | 89 ++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index fc01f46d..d0b01245 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -60,6 +60,27 @@ contract DecentHats { string topHatDetails; string topHatImageURI; } + struct CreateRoleHatParams { + IHats hatsProtocol; + IERC6551Registry registry; + address topHatAccount; + address hatsAccountImplementation; + uint256 adminHatId; + uint256 topHatId; + Hat hat; + } + + struct CreateTermedRoleHatParams { + IHats hatsProtocol; + IERC6551Registry registry; + IHatsModuleFactory hatsModuleFactory; + address topHatAccount; + address hatsAccountImplementation; + address hatsElectionEligibilityImplementation; + uint256 adminHatId; + uint256 topHatId; + Hat hat; + } /* ///////////////////////////////////////////////////////////////////////////// EXTERNAL FUNCTIONS @@ -146,25 +167,59 @@ contract DecentHats { * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. * See: https://github.com/decentdao/decent-interface/issues/2402 */ - function createRoleHat( - IHats hatsProtocol, - IERC6551Registry registry, - address topHatAccount, - address hatsAccountImplementation, - uint256 adminHatId, - uint256 topHatId, - Hat calldata hat - ) public returns (uint256 hatId, address accountAddress) { - (hatId, accountAddress) = _createHatAndAccountAndMintAndStreams( - hatsProtocol, - registry, - topHatAccount, - hatsAccountImplementation, - adminHatId, - hat + function createRoleHat(CreateRoleHatParams calldata params) external { + _createHatAndAccountAndMintAndStreams( + params.hatsProtocol, + params.registry, + params.topHatAccount, + params.hatsAccountImplementation, + params.adminHatId, + params.hat + ); + + params.hatsProtocol.transferHat( + params.topHatId, + address(this), + msg.sender ); + } - hatsProtocol.transferHat(topHatId, address(this), msg.sender); + /** + * Creates a new terned role hat and any streams on it. + * + * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. + * In order for the module to be able to create hats on behalf of the Safe, the Safe must first + * transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * creating the role hat. + * + * The function simply calls `createTermedHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * + * @dev Termed Role hat creation, minting, and stream creation are handled here in order + * to avoid a race condition where not more than one active proposal to create a new termed role can exist at a time. + * See: https://github.com/decentdao/decent-interface/issues/2402 + */ + function createTermedRoleHat( + CreateTermedRoleHatParams calldata params + ) external { + _createTermedHatAndAccountAndMintAndStreams( + params.hatsProtocol, + params.topHatAccount, + _createElectionEligiblityModule( + params.hatsModuleFactory, + params.hatsElectionEligibilityImplementation, + params.hatsProtocol.getNextId(params.adminHatId), + params.topHatId, + params.hat.termedParams[0] + ), + params.adminHatId, + params.hat + ); + + params.hatsProtocol.transferHat( + params.topHatId, + address(this), + msg.sender + ); } /* ///////////////////////////////////////////////////////////////////////////// From e84b682219f750e2e1724fd4bea3db936d2e05ea Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 13:53:40 -0400 Subject: [PATCH 127/206] switch createAndDeclareTree function to external --- contracts/DecentHats.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index d0b01245..33f9cd89 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -96,7 +96,7 @@ contract DecentHats { * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. */ - function createAndDeclareTree(CreateTreeParams calldata params) public { + function createAndDeclareTree(CreateTreeParams calldata params) external { (uint256 topHatId, address topHatAccount) = _createTopHatAndAccount( params.hatsProtocol, params.topHatDetails, From c9a5009e73e16bead5c202a74868fb1cca997c13 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 13:54:23 -0400 Subject: [PATCH 128/206] move Create Sablier Stream logic to internal function --- contracts/DecentHats.sol | 118 +++++++++++++++------------------------ 1 file changed, 45 insertions(+), 73 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 33f9cd89..ee46ed63 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -60,6 +60,7 @@ contract DecentHats { string topHatDetails; string topHatImageURI; } + struct CreateRoleHatParams { IHats hatsProtocol; IERC6551Registry registry; @@ -328,43 +329,7 @@ contract DecentHats { hatsProtocol.mintHat(hatId, hat.wearer); for (uint256 i = 0; i < hat.sablierParams.length; ) { - SablierStreamParams memory sablierParams = hat.sablierParams[i]; - - // Approve tokens for Sablier - IAvatar(msg.sender).execTransactionFromModule( - sablierParams.asset, - 0, - abi.encodeWithSignature( - "approve(address,uint256)", - sablierParams.sablier, - sablierParams.totalAmount - ), - Enum.Operation.Call - ); - - LockupLinear.CreateWithTimestamps memory params = LockupLinear - .CreateWithTimestamps({ - sender: sablierParams.sender, - recipient: accountAddress, - totalAmount: sablierParams.totalAmount, - asset: IERC20(sablierParams.asset), - cancelable: sablierParams.cancelable, - transferable: sablierParams.transferable, - timestamps: sablierParams.timestamps, - broker: sablierParams.broker - }); - - // Proxy the Sablier call through IAvatar - IAvatar(msg.sender).execTransactionFromModule( - address(sablierParams.sablier), - 0, - abi.encodeWithSignature( - "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", - params - ), - Enum.Operation.Call - ); - + _createSablierStream(hat.sablierParams[i], hat.wearer); unchecked { ++i; } @@ -402,43 +367,10 @@ contract DecentHats { hatsProtocol.mintHat(hatId, hat.termedParams[0].nominatedWearers[0]); for (uint256 i = 0; i < hat.sablierParams.length; ) { - SablierStreamParams memory sablierParams = hat.sablierParams[i]; - - // Approve tokens for Sablier - IAvatar(msg.sender).execTransactionFromModule( - sablierParams.asset, - 0, - abi.encodeWithSignature( - "approve(address,uint256)", - sablierParams.sablier, - sablierParams.totalAmount - ), - Enum.Operation.Call - ); - - LockupLinear.CreateWithTimestamps memory params = LockupLinear - .CreateWithTimestamps({ - sender: sablierParams.sender, - recipient: hat.termedParams[0].nominatedWearers[0], - totalAmount: sablierParams.totalAmount, - asset: IERC20(sablierParams.asset), - cancelable: sablierParams.cancelable, - transferable: sablierParams.transferable, - timestamps: sablierParams.timestamps, - broker: sablierParams.broker - }); - - // Proxy the Sablier call through IAvatar - IAvatar(msg.sender).execTransactionFromModule( - address(sablierParams.sablier), - 0, - abi.encodeWithSignature( - "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", - params - ), - Enum.Operation.Call + _createSablierStream( + hat.sablierParams[i], + hat.termedParams[0].nominatedWearers[0] ); - unchecked { ++i; } @@ -495,4 +427,44 @@ contract DecentHats { uint256(SALT) ); } + + function _createSablierStream( + SablierStreamParams memory sablierParams, + address recipient + ) internal { + // Approve tokens for Sablier + IAvatar(msg.sender).execTransactionFromModule( + sablierParams.asset, + 0, + abi.encodeWithSignature( + "approve(address,uint256)", + sablierParams.sablier, + sablierParams.totalAmount + ), + Enum.Operation.Call + ); + + LockupLinear.CreateWithTimestamps memory params = LockupLinear + .CreateWithTimestamps({ + sender: sablierParams.sender, + recipient: recipient, + totalAmount: sablierParams.totalAmount, + asset: IERC20(sablierParams.asset), + cancelable: sablierParams.cancelable, + transferable: sablierParams.transferable, + timestamps: sablierParams.timestamps, + broker: sablierParams.broker + }); + + // Proxy the Sablier call through IAvatar + IAvatar(msg.sender).execTransactionFromModule( + address(sablierParams.sablier), + 0, + abi.encodeWithSignature( + "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", + params + ), + Enum.Operation.Call + ); + } } From d3c885d5f98897f787340831213d6b62c5928c31 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:16:33 -0400 Subject: [PATCH 129/206] fix sablier recipient for role hats --- contracts/DecentHats.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index ee46ed63..0ce8374a 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -329,7 +329,7 @@ contract DecentHats { hatsProtocol.mintHat(hatId, hat.wearer); for (uint256 i = 0; i < hat.sablierParams.length; ) { - _createSablierStream(hat.sablierParams[i], hat.wearer); + _createSablierStream(hat.sablierParams[i], accountAddress); unchecked { ++i; } From 22b492a39415e5761fdf555b7a2555811a3b1646 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:39:29 -0400 Subject: [PATCH 130/206] update tests to latest - matches DecentHats test to original contract - adds eslint ignore for ethers import for type-safety --- test/DecentHats.test.ts | 380 ++++++++++++++++++++-------------- test/DecentHats_0_1_0.test.ts | 4 +- test/helpers.ts | 4 +- 3 files changed, 229 insertions(+), 159 deletions(-) diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index 8063981a..b0fd8912 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -1,6 +1,9 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { expect } from 'chai'; -import hre, { ethers } from 'hardhat'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import { ethers } from 'ethers'; +import hre from 'hardhat'; + import { GnosisSafeL2, GnosisSafeL2__factory, @@ -18,58 +21,16 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, - MockHatsModuleFactory__factory, + DecentAutonomousAdmin, + DecentAutonomousAdmin__factory, MockHatsElectionEligibility__factory, - ModuleProxyFactory__factory, + MockHatsModuleFactory__factory, ModuleProxyFactory, - DecentAutonomousAdmin__factory, - DecentAutonomousAdmin, + ModuleProxyFactory__factory, } from '../typechain-types'; import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; -import { - buildSafeTransaction, - buildSignatureBytes, - predictGnosisSafeAddress, - safeSignTypedData, -} from './helpers'; - -const executeSafeTransaction = async ({ - safe, - to, - transactionData, - signers, -}: { - safe: GnosisSafeL2; - to: string; - transactionData: string; - signers: SignerWithAddress[]; -}) => { - const safeTx = buildSafeTransaction({ - to, - data: transactionData, - nonce: await safe.nonce(), - }); - - const sigs = await Promise.all( - signers.map(async signer => safeSignTypedData(signer, safe, safeTx)), - ); - - const tx = await safe.execTransaction( - safeTx.to, - safeTx.value, - safeTx.data, - safeTx.operation, - safeTx.safeTxGas, - safeTx.baseGas, - safeTx.gasPrice, - safeTx.gasToken, - safeTx.refundReceiver, - buildSignatureBytes(sigs), - ); - - return tx; -}; +import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; describe('DecentHats', () => { let dao: SignerWithAddress; @@ -100,74 +61,75 @@ describe('DecentHats', () => { let moduleProxyFactory: ModuleProxyFactory; let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; - beforeEach(async () => { - const signers = await hre.ethers.getSigners(); - const [deployer] = signers; - [, dao] = signers; - - mockHats = await new MockHats__factory(deployer).deploy(); - mockHatsAddress = await mockHats.getAddress(); - const mockHatsElectionEligibilityImplementation = - await new MockHatsElectionEligibility__factory(deployer).deploy(); - mockHatsElectionEligibilityImplementationAddress = - await mockHatsElectionEligibilityImplementation.getAddress(); - const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); - mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); - keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); - erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); - mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHats__factory(deployer).deploy(); - decentHatsAddress = await decentHats.getAddress(); - - moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); - decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); - - const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); - const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( - 'setup', - [ - [dao.address], - 1, - hre.ethers.ZeroAddress, - hre.ethers.ZeroHash, - hre.ethers.ZeroAddress, - hre.ethers.ZeroAddress, - 0, - hre.ethers.ZeroAddress, - ], - ); - - const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); - - const predictedGnosisSafeAddress = await predictGnosisSafeAddress( - createGnosisSetupCalldata, - saltNum, - gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory, - ); - gnosisSafeAddress = predictedGnosisSafeAddress; - - await gnosisSafeProxyFactory.createProxyWithNonce( - gnosisSafeL2SingletonAddress, - createGnosisSetupCalldata, - saltNum, - ); - - gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); - - // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); - mockSablierAddress = await mockSablier.getAddress(); - - mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); - mockERC20Address = await mockERC20.getAddress(); - - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); + try { + const signers = await hre.ethers.getSigners(); + const [deployer] = signers; + [, dao] = signers; + + mockHats = await new MockHats__factory(deployer).deploy(); + mockHatsAddress = await mockHats.getAddress(); + const mockHatsElectionEligibilityImplementation = + await new MockHatsElectionEligibility__factory(deployer).deploy(); + mockHatsElectionEligibilityImplementationAddress = + await mockHatsElectionEligibilityImplementation.getAddress(); + const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); + mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); + decentHats = await new DecentHats__factory(deployer).deploy(); + decentHatsAddress = await decentHats.getAddress(); + moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'setup', + [ + [dao.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ], + ); + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); + + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( + createGnosisSetupCalldata, + saltNum, + gnosisSafeL2SingletonAddress, + gnosisSafeProxyFactory, + ); + gnosisSafeAddress = predictedGnosisSafeAddress; + + await gnosisSafeProxyFactory.createProxyWithNonce( + gnosisSafeL2SingletonAddress, + createGnosisSetupCalldata, + saltNum, + ); + + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); + + // Deploy MockSablierV2LockupLinear + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockSablierAddress = await mockSablier.getAddress(); + + mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); + mockERC20Address = await mockERC20.getAddress(); + + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); + } catch (e) { + console.error('AHHHHHH', e); + } }); describe('DecentHats as a Module', () => { @@ -220,12 +182,7 @@ describe('DecentHats', () => { wearer: ethers.ZeroAddress, sablierParams: [], isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParams: [], }, hats: [ { @@ -236,12 +193,7 @@ describe('DecentHats', () => { wearer: ethers.ZeroAddress, sablierParams: [], isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParams: [], }, { maxSupply: 1, @@ -251,12 +203,7 @@ describe('DecentHats', () => { wearer: ethers.ZeroAddress, sablierParams: [], isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParams: [], }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -349,34 +296,17 @@ describe('DecentHats', () => { }); describe('Creating Hats Accounts', () => { - let salt: string; - - beforeEach(async () => { - salt = await decentHats.SALT(); - }); - - const getHatAccount = async (hatId: bigint) => { - const hatAccountAddress = await erc6551Registry.account( - mockHatsAccountImplementationAddress, - salt, - await hre.getChainId(), - mockHatsAddress, - hatId, - ); - - const hatAccount = MockHatsAccount__factory.connect( - hatAccountAddress, - hre.ethers.provider, - ); - - return hatAccount; - }; - it('Generates the correct Addresses for the current Hats', async () => { const currentCount = await mockHats.count(); for (let i = 0n; i < currentCount; i++) { - const topHatAccount = await getHatAccount(i); + const topHatAccount = await getHatAccount( + i, + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress, + ); + expect(await topHatAccount.tokenId()).eq(i); expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); } @@ -666,5 +596,141 @@ describe('DecentHats', () => { expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); }); }); + + describe('Creating a new hat on existing Tree', () => { + let createRoleHatPromise: Promise; + const topHatId = 0; + + beforeEach(async () => { + try { + await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [], + }, + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + moduleProxyFactory: await moduleProxyFactory.getAddress(), + decentAutonomousAdminMasterCopy: + await decentAutonomousAdminMasterCopy.getAddress(), + hats: [], + }, + ], + ), + signers: [dao], + }); + } catch (e) { + console.error('Error creating tree', e); + } + const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + + createRoleHatPromise = executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats__factory.createInterface().encodeFunctionData( + 'createRoleHat', + [ + { + hatsProtocol: mockHatsAddress, + registry: await erc6551Registry.getAddress(), + topHatAccount: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + hatsAccountImplementation: mockHatsAccountImplementationAddress, + adminHatId: 1, + topHatId, + hat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: true, + wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + isTermed: false, + termedParams: [], + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + }, + ], + ), + signers: [dao], + }); + }); + + it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { + await expect(createRoleHatPromise).to.be.reverted; + }); + + it('Emits an ExecutionSuccess event', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); + + it('Emits an ExecutionFromModuleSuccess event', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await expect(await createRoleHatPromise) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); + + it('Transfers the top hat back to the Safe', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + + const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); + expect(isModuleWearerOfTopHat).to.equal(true); + + await createRoleHatPromise; + + const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); + expect(isSafeWearerOfTopHat).to.equal(true); + }); + + it('Actually creates the new hat', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + + const hatsCountBeforeCreate = await mockHats.count(); + expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat + + await createRoleHatPromise; + + const newHatId = await mockHats.count(); + expect(newHatId).to.equal(3); // + newly created hat + }); + }); }); }); diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 7ffb285e..dd9a3654 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -1,6 +1,8 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { expect } from 'chai'; -import hre, { ethers } from 'hardhat'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import { ethers } from 'ethers'; +import hre from 'hardhat'; import { GnosisSafeL2, GnosisSafeL2__factory, diff --git a/test/helpers.ts b/test/helpers.ts index 17826296..d8b42c2e 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,5 +1,7 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; -import hre, { ethers } from 'hardhat'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import { ethers } from 'ethers'; +import hre from 'hardhat'; import { ERC6551Registry, GnosisSafeL2, From b0f9ec5289850d0ec4bcc905ff96a35653885449 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:24:46 -0400 Subject: [PATCH 131/206] update eligibility mock contract to more align with live contract --- .../mocks/MockHatsElectionEligibility.sol | 52 +++++++++---------- contracts/mocks/MockHatsModuleFactory.sol | 32 ++++-------- 2 files changed, 35 insertions(+), 49 deletions(-) diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionEligibility.sol index d9d8daab..5c9c4212 100644 --- a/contracts/mocks/MockHatsElectionEligibility.sol +++ b/contracts/mocks/MockHatsElectionEligibility.sol @@ -1,41 +1,37 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; +import {IHatsElectionEligibility} from "../interfaces/hats/full/IHatsElectionEligibility.sol"; -contract MockHatsElectionEligibility { - uint128 private _currentTermEnd; - uint128 private _nextTermEnd; - mapping(uint128 => bool) private _electionStatus; +contract MockHatsElectionEligibility is IHatsElectionEligibility { + function currentTermEnd() external view returns (uint128) {} - event ElectionOpened(uint128 nextTermEnd); - event ElectionCompleted(uint128 termEnd, address[] winners); - event NewTermStarted(uint128 termEnd); + function nextTermEnd() external view returns (uint128) {} - // Mock function to simulate starting the next term - function startNextTerm() external { - _currentTermEnd = _nextTermEnd; - _nextTermEnd = 0; + function electionStatus( + uint128 termEnd + ) external view returns (bool isElectionOpen) {} - emit NewTermStarted(_currentTermEnd); - } + function electionResults( + uint128 termEnd, + address candidate + ) external view returns (bool elected) {} - function currentTermEnd() external view returns (uint128) { - return _currentTermEnd; - } + function BALLOT_BOX_HAT() external pure returns (uint256) {} - function electionStatus(uint128 termEnd) external view returns (bool) { - return _electionStatus[termEnd]; - } + function ADMIN_HAT() external pure returns (uint256) {} - // Functions to set the mock data for testing - function setCurrentTermEnd(uint128 termEnd) external { - _currentTermEnd = termEnd; - } + function elect(uint128 _termEnd, address[] calldata _winners) external {} - function setNextTermEnd(uint128 termEnd) external { - _nextTermEnd = termEnd; - } + function recall(uint128 _termEnd, address[] calldata _recallees) external {} + + function setNextTerm(uint128 _newTermEnd) external {} + + function startNextTerm() external {} - function setElectionStatus(uint128 termEnd, bool status) external { - _electionStatus[termEnd] = status; + function getWearerStatus( + address, + uint256 + ) external pure returns (bool eligible, bool standing) { + return (true, true); } } diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol index 944d3401..df5479d3 100644 --- a/contracts/mocks/MockHatsModuleFactory.sol +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -2,22 +2,19 @@ pragma solidity ^0.8.19; import {IHatsModuleFactory} from "../interfaces/hats/full/IHatsModuleFactory.sol"; +import {MockHatsElectionEligibility} from "./MockHatsElectionEligibility.sol"; contract MockHatsModuleFactory is IHatsModuleFactory { function createHatsModule( - address _implementation, - uint256 _hatId, - bytes calldata _otherImmutableArgs, - bytes calldata _initData, - uint256 _saltNonce - ) external pure returns (address _instance) { - // Silence unused variable warnings - _implementation; - _hatId; - _otherImmutableArgs; - _initData; - _saltNonce; - return address(0); + address, + uint256, + bytes calldata, + bytes calldata, + uint256 + ) external override returns (address _instance) { + // Deploy a new instance of MockHatsElectionEligibility + MockHatsElectionEligibility newModule = new MockHatsElectionEligibility(); + _instance = address(newModule); } function getHatsModuleAddress( @@ -25,14 +22,7 @@ contract MockHatsModuleFactory is IHatsModuleFactory { uint256 _hatId, bytes calldata _otherImmutableArgs, uint256 _saltNonce - ) external pure returns (address) { - // Silence unused variable warnings - _implementation; - _hatId; - _otherImmutableArgs; - _saltNonce; - return address(0); - } + ) external view returns (address) {} function HATS() external view override returns (address) {} From 44e1e2d8f050486108edf47ba963748aabd62905 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:24:54 -0400 Subject: [PATCH 132/206] add `getNextId` method --- contracts/mocks/MockHats.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index a070189d..c7adc972 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -58,4 +58,8 @@ contract MockHats is IHats { function getHatEligibilityModule( uint256 _hatId ) external view returns (address eligibility) {} + + function getNextId(uint256) external view returns (uint256 nextId) { + nextId = count; + } } From 81b9ac08b3e589d31b9d19ec63b1ed97d582a261 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sat, 26 Oct 2024 21:25:18 -0400 Subject: [PATCH 133/206] add 'create tree with term roles' tests --- test/DecentHats.test.ts | 90 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index b0fd8912..166dca67 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -69,12 +69,15 @@ describe('DecentHats', () => { mockHats = await new MockHats__factory(deployer).deploy(); mockHatsAddress = await mockHats.getAddress(); + const mockHatsElectionEligibilityImplementation = await new MockHatsElectionEligibility__factory(deployer).deploy(); mockHatsElectionEligibilityImplementationAddress = await mockHatsElectionEligibilityImplementation.getAddress(); + const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); @@ -313,6 +316,93 @@ describe('DecentHats', () => { }); }); }); + describe('Creating a new Top Hat and Tree with Termed Roles', () => { + let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + + beforeEach(async () => { + createAndDeclareTreeTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + moduleProxyFactory: await moduleProxyFactory.getAddress(), + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [], + }, + hats: [ + { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: true, + termedParams: [ + { + termEndDateTs: BigInt(Date.now() + 100000), + nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], + }, + ], + }, + { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: true, + termedParams: [ + { + termEndDateTs: BigInt(Date.now() + 100000), + nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], + }, + ], + }, + ], + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + }, + ], + ), + signers: [dao], + }); + }); + + it('Emits an ExecutionSuccess event', async () => { + await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); + + it('Emits an ExecutionFromModuleSuccess event', async () => { + await expect(createAndDeclareTreeTx) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); + + it('Emits some hatsTreeId ValueUpdated events', async () => { + await expect(createAndDeclareTreeTx) + .to.emit(keyValuePairs, 'ValueUpdated') + .withArgs(gnosisSafeAddress, 'topHatId', '0'); + }); + }); describe('Creating a new Top Hat and Tree with Sablier Streams', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; From d2b15f1714c17f6830efb06a0bf901b648e03cee Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:28:42 -0400 Subject: [PATCH 134/206] eslint ignore ethers import --- test/DecentSablierStreamManagement.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index de11ac61..360eaa4a 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -1,6 +1,8 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { expect } from 'chai'; -import hre, { ethers } from 'hardhat'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import { ethers } from 'ethers'; +import hre from 'hardhat'; import { DecentHats_0_1_0, DecentHats_0_1_0__factory, From 866716c3fc418ab3ef67cb694e73326a657496e0 Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 18:15:19 +0100 Subject: [PATCH 135/206] Update natspec --- contracts/DecentHats_0_1_0.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index a44756ee..df2b9a4b 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -196,14 +196,14 @@ contract DecentHats_0_1_0 { } /** - * Creates a new role hat and any streams on it. + * @notice Creates a new role hat and any streams on it. * - * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. - * In order for the module to be able to create hats on behalf of the Safe, the Safe must first - * transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disabled after. + * + * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after * creating the role hat. * - * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * @dev The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. @@ -233,10 +233,10 @@ contract DecentHats_0_1_0 { } /** - * For a safe without any roles previously created on it, this function should be called. It sets up the + * @notice For a safe without any roles previously created on it, this function should be called. It sets up the * top hat and admin hat, as well as any other hats and their streams that are provided. * - * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. + * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. * * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, From 4d4edb8142ea35236988a74879a7cc18bb57b7fb Mon Sep 17 00:00:00 2001 From: Kellar Date: Mon, 28 Oct 2024 13:04:24 +0000 Subject: [PATCH 136/206] Put natspec update in the correct contract --- contracts/DecentHats.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 0ce8374a..7660c33c 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -87,10 +87,10 @@ contract DecentHats { EXTERNAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ /** - * For a safe without any roles previously created on it, this function should be called. It sets up the + * @notice For a safe without any roles previously created on it, this function should be called. It sets up the * top hat and admin hat, as well as any other hats and their streams that are provided. * - * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. + * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. * * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, @@ -155,14 +155,14 @@ contract DecentHats { } /** - * Creates a new role hat and any streams on it. + * @notice Creates a new role hat and any streams on it. * - * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. - * In order for the module to be able to create hats on behalf of the Safe, the Safe must first - * transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disabled after. + * + * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after * creating the role hat. * - * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * @dev The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. From c9cde2b092e617fd3cec4b33b5b0c80a75f40c41 Mon Sep 17 00:00:00 2001 From: Kellar Date: Mon, 28 Oct 2024 13:10:25 +0000 Subject: [PATCH 137/206] Cleanup natspec --- contracts/DecentHats.sol | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 7660c33c..cf1c520b 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -88,7 +88,8 @@ contract DecentHats { ///////////////////////////////////////////////////////////////////////////// */ /** * @notice For a safe without any roles previously created on it, this function should be called. It sets up the - * top hat and admin hat, as well as any other hats and their streams that are provided. + * top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat + * to the calling safe. * * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. * @@ -159,10 +160,11 @@ contract DecentHats { * * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disabled after. * - * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first + * transfer its top hat to this contract. This function transfers the top hat back to the Safe after * creating the role hat. * - * @dev The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * @dev The function simply calls `_createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. @@ -186,14 +188,15 @@ contract DecentHats { } /** - * Creates a new terned role hat and any streams on it. + * @notice Creates a new termed role hat and any streams on it. + * + * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disable after. * - * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. - * In order for the module to be able to create hats on behalf of the Safe, the Safe must first + * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first * transfer its top hat to this contract. This function transfers the top hat back to the Safe after * creating the role hat. * - * The function simply calls `createTermedHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * @dev The function simply calls `_createTermedHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * * @dev Termed Role hat creation, minting, and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new termed role can exist at a time. From 6b0f5c80e4cff688f6ccca11fa5bb82ac2174f0f Mon Sep 17 00:00:00 2001 From: Kellar Date: Mon, 28 Oct 2024 13:43:49 +0000 Subject: [PATCH 138/206] Add natspec clarifying stream recipient difference between termed and untermed roles --- contracts/DecentHats.sol | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index cf1c520b..52159e22 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -93,6 +93,12 @@ contract DecentHats { * * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. * + * @dev For each hat that is included, if the hat is: + * - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-` + * on the Sablier contract. + * - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the + * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer. + * * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. @@ -166,6 +172,9 @@ contract DecentHats { * * @dev The function simply calls `_createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * + * @dev Stream funds on Roles are targeted at the hat's smart account. In order to withdraw funds from the stream, the + * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer. + * * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. * See: https://github.com/decentdao/decent-interface/issues/2402 @@ -198,6 +207,9 @@ contract DecentHats { * * @dev The function simply calls `_createTermedHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * + * @dev Stream funds on Termed Roles are targeted directly at the nominated wearer. + * The wearer should directly call `withdraw-` on the Sablier contract. + * * @dev Termed Role hat creation, minting, and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new termed role can exist at a time. * See: https://github.com/decentdao/decent-interface/issues/2402 From 2551fbf079de3c6176c4e8baafb9a57455a56027 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:15:14 -0400 Subject: [PATCH 139/206] fix typo --- test/DecentAutonomousAdmin.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index fa4a2c49..212c1d3d 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -97,7 +97,7 @@ describe('DecentAutonomousAdminHat', function () { sablierStreamInfo: [], // No Sablier stream info for this test }; - // Verify the hat is now worn by the current wearer + // revert if not the current wearer await expect(adminHat.connect(randomUser).triggerStartNextTerm(args)).to.be.revertedWith( 'Not current wearer', ); From b066efa43272ef31df176c15cf851eb54333f01e Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:19:13 -0400 Subject: [PATCH 140/206] expect the hat wearer to lose hat --- contracts/mocks/MockHatsAdmin.sol | 8 ++++++-- test/DecentAutonomousAdmin.test.ts | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/contracts/mocks/MockHatsAdmin.sol b/contracts/mocks/MockHatsAdmin.sol index 9fc250b4..bddb1368 100644 --- a/contracts/mocks/MockHatsAdmin.sol +++ b/contracts/mocks/MockHatsAdmin.sol @@ -159,8 +159,12 @@ contract MockHatsAutoAdmin is IHats { function checkHatWearerStatus( uint256 _hatId, - address _wearer - ) external override returns (bool updated) {} + address + ) external override returns (bool updated) { + // 'burns' the hat if the wearer is no longer eligible + wearer[_hatId] = address(0); + return true; + } function renounceHat(uint256 _hatId) external override {} diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index 212c1d3d..7061b1ac 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -87,6 +87,8 @@ describe('DecentAutonomousAdminHat', function () { // Verify the hat is now worn by the nominated wearer expect((await hatsProtocol.isWearerOfHat(nominatedWearer.address, userHatId)) === true); + + expect((await hatsProtocol.isWearerOfHat(currentWearer.address, userHatId)) === false); }); it('should correctly invalidate random address as current wearer', async function () { const args = { From a58bad4fd23c6a6191bf4bbefc7808c0dcec63f3 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 10:24:56 -0400 Subject: [PATCH 141/206] add test for `createTermedRoleHat` --- test/DecentHats.test.ts | 144 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index 166dca67..56fdcbe8 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -822,5 +822,149 @@ describe('DecentHats', () => { expect(newHatId).to.equal(3); // + newly created hat }); }); + + describe('Creating a new hat on existing Tree', () => { + let createRoleHatPromise: Promise; + const topHatId = 0; + + beforeEach(async () => { + try { + await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + hatsAccountImplementation: mockHatsAccountImplementationAddress, + registry: await erc6551Registry.getAddress(), + keyValuePairs: await keyValuePairs.getAddress(), + topHatDetails: '', + topHatImageURI: '', + adminHat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: false, + wearer: ethers.ZeroAddress, + sablierParams: [], + isTermed: false, + termedParams: [], + }, + hatsModuleFactory: mockHatsModuleFactoryAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + moduleProxyFactory: await moduleProxyFactory.getAddress(), + decentAutonomousAdminMasterCopy: + await decentAutonomousAdminMasterCopy.getAddress(), + hats: [], + }, + ], + ), + signers: [dao], + }); + } catch (e) { + console.error('Error creating tree', e); + } + const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + + createRoleHatPromise = executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsAddress, + transactionData: DecentHats__factory.createInterface().encodeFunctionData( + 'createTermedRoleHat', + [ + { + hatsProtocol: mockHatsAddress, + registry: await erc6551Registry.getAddress(), + topHatAccount: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + hatsAccountImplementation: mockHatsAccountImplementationAddress, + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + hatsModuleFactory: mockHatsModuleFactoryAddress, + adminHatId: 1, + topHatId, + hat: { + maxSupply: 1, + details: '', + imageURI: '', + isMutable: true, + wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + isTermed: true, + termedParams: [ + { + termEndDateTs: BigInt(Date.now() + 100000), + nominatedWearers: ['0xdce7ca0555101f97451926944f5ae3b7adb2f5ae'], + }, + ], + sablierParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + }, + }, + ], + ), + signers: [dao], + }); + }); + + it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { + await expect(createRoleHatPromise).to.be.reverted; + }); + + it('Emits an ExecutionSuccess event', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); + + it('Emits an ExecutionFromModuleSuccess event', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await expect(await createRoleHatPromise) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsAddress); + }); + + it('Transfers the top hat back to the Safe', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + + const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); + expect(isModuleWearerOfTopHat).to.equal(true); + + await createRoleHatPromise; + + const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); + expect(isSafeWearerOfTopHat).to.equal(true); + }); + + it('Actually creates the new hat', async () => { + // First transfer the top hat to the Safe + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + + const hatsCountBeforeCreate = await mockHats.count(); + expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat + + await createRoleHatPromise; + + const newHatId = await mockHats.count(); + expect(newHatId).to.equal(3); // + newly created hat + }); + }); }); }); From 0df6616495b87f7f414ba4116edadd689dfcb2ff Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 29 Oct 2024 15:09:19 +0000 Subject: [PATCH 142/206] Revert misplaced natspec update --- contracts/DecentHats_0_1_0.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol index df2b9a4b..a44756ee 100644 --- a/contracts/DecentHats_0_1_0.sol +++ b/contracts/DecentHats_0_1_0.sol @@ -196,14 +196,14 @@ contract DecentHats_0_1_0 { } /** - * @notice Creates a new role hat and any streams on it. + * Creates a new role hat and any streams on it. * - * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disabled after. - * - * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after + * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. + * In order for the module to be able to create hats on behalf of the Safe, the Safe must first + * transfer its top hat to this contract. This function transfers the top hat back to the Safe after * creating the role hat. * - * @dev The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. + * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. * * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. @@ -233,10 +233,10 @@ contract DecentHats_0_1_0 { } /** - * @notice For a safe without any roles previously created on it, this function should be called. It sets up the + * For a safe without any roles previously created on it, this function should be called. It sets up the * top hat and admin hat, as well as any other hats and their streams that are provided. * - * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. + * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. * * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, From 0f211e0d146d7f305ad788dd0c807f38ce33b9a0 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 29 Oct 2024 12:10:50 -0400 Subject: [PATCH 143/206] Remove unused import from interface --- contracts/interfaces/IDecentAutonomousAdmin.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentAutonomousAdmin.sol index 2bcc99b0..d0c55200 100644 --- a/contracts/interfaces/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/IDecentAutonomousAdmin.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.28; import {IHats} from "./hats/full/IHats.sol"; -import {ISablierV2Lockup} from "./sablier/full/ISablierV2Lockup.sol"; interface IDecentAutonomousAdmin { struct TriggerStartArgs { From 2ecdbdc2da004b0a7f04b06e1c28e149df3538f3 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 29 Oct 2024 13:05:23 -0400 Subject: [PATCH 144/206] Consolidate Mock Hats into a single contract --- contracts/DecentAutonomousAdmin.sol | 16 +- .../interfaces/IDecentAutonomousAdmin.sol | 4 +- contracts/mocks/MockHats.sol | 270 +++++++++++++++-- contracts/mocks/MockHatsAdmin.sol | 284 ------------------ test/DecentAutonomousAdmin.test.ts | 21 +- test/DecentHats.test.ts | 20 +- test/DecentHats_0_1_0.test.ts | 6 +- 7 files changed, 274 insertions(+), 347 deletions(-) delete mode 100644 contracts/mocks/MockHatsAdmin.sol diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 9a18997c..07c38c97 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -22,15 +22,12 @@ contract DecentAutonomousAdmin is // ////////////////////////////////////////////////////////////// function triggerStartNextTerm(TriggerStartArgs calldata args) public { require( - args.userHatProtocol.isWearerOfHat( - args.currentWearer, - args.userHatId - ), + args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId), "Not current wearer" ); address hatsEligibilityModuleAddress = args - .userHatProtocol - .getHatEligibilityModule(args.userHatId); + .hatsProtocol + .getHatEligibilityModule(args.hatId); IHatsElectionEligibility hatsElectionModule = IHatsElectionEligibility( hatsEligibilityModuleAddress @@ -39,12 +36,9 @@ contract DecentAutonomousAdmin is hatsElectionModule.startNextTerm(); // This will burn the hat since wearer is no longer eligible - args.userHatProtocol.checkHatWearerStatus( - args.userHatId, - args.currentWearer - ); + args.hatsProtocol.checkHatWearerStatus(args.hatId, args.currentWearer); // This will mint the hat to the nominated wearer - args.userHatProtocol.mintHat(args.userHatId, args.nominatedWearer); + args.hatsProtocol.mintHat(args.hatId, args.nominatedWearer); } function supportsInterface( diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentAutonomousAdmin.sol index d0c55200..affa38bf 100644 --- a/contracts/interfaces/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/IDecentAutonomousAdmin.sol @@ -6,8 +6,8 @@ import {IHats} from "./hats/full/IHats.sol"; interface IDecentAutonomousAdmin { struct TriggerStartArgs { address currentWearer; - IHats userHatProtocol; - uint256 userHatId; + IHats hatsProtocol; + uint256 hatId; address nominatedWearer; } diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index c7adc972..2a3b2b4a 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -1,65 +1,285 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -import {IHats} from "../interfaces/hats/IHats.sol"; +import {IHats} from "../interfaces/hats/full/IHats.sol"; contract MockHats is IHats { - uint256 public count = 0; - mapping(uint256 => address) hatWearers; + uint256 public hatId = 0; + mapping(uint256 => address) public wearers; + mapping(uint256 => address) public eligibility; + + event HatCreated(uint256 hatId); function mintTopHat( address _target, string memory, string memory ) external returns (uint256 topHatId) { - topHatId = count; - count++; - hatWearers[topHatId] = _target; + topHatId = hatId; + hatId++; + wearers[topHatId] = _target; } function createHat( uint256, string calldata, uint32, - address, + address _eligibility, address, bool, string calldata ) external returns (uint256 newHatId) { - newHatId = count; - count++; + newHatId = hatId; + hatId++; + eligibility[hatId] = _eligibility; + emit HatCreated(hatId); } function mintHat( - uint256 hatId, - address wearer + uint256 _hatId, + address _wearer ) external returns (bool success) { success = true; - hatWearers[hatId] = wearer; + wearers[_hatId] = _wearer; } function transferHat(uint256 _hatId, address _from, address _to) external { - require( - hatWearers[_hatId] == _from, - "MockHats: Invalid current wearer" - ); - hatWearers[_hatId] = _to; + require(wearers[_hatId] == _from, "MockHats: Invalid current wearer"); + wearers[_hatId] = _to; } function isWearerOfHat( - address _user, + address _wearer, uint256 _hatId - ) external view returns (bool isWearer) { - isWearer = hatWearers[_hatId] == _user; + ) external view override returns (bool) { + return _wearer == wearers[_hatId]; } - function changeHatEligibility(uint256, address) external {} - function getHatEligibilityModule( uint256 _hatId - ) external view returns (address eligibility) {} + ) external view override returns (address) { + return eligibility[_hatId]; + } + + function changeHatEligibility( + uint256 _hatId, + address _newEligibility + ) external override { + eligibility[_hatId] = _newEligibility; + } + + function buildHatId( + uint256 _admin, + uint16 _newHat + ) external pure override returns (uint256 id) {} + + function getHatLevel( + uint256 _hatId + ) external view override returns (uint32 level) {} + + function getLocalHatLevel( + uint256 _hatId + ) external pure override returns (uint32 level) {} + + function isTopHat( + uint256 _hatId + ) external view override returns (bool _topHat) {} + + function isLocalTopHat( + uint256 _hatId + ) external pure override returns (bool _localTopHat) {} + + function isValidHatId( + uint256 _hatId + ) external view override returns (bool validHatId) {} + + function getAdminAtLevel( + uint256 _hatId, + uint32 _level + ) external view override returns (uint256 admin) {} + + function getAdminAtLocalLevel( + uint256 _hatId, + uint32 _level + ) external pure override returns (uint256 admin) {} + + function getTopHatDomain( + uint256 _hatId + ) external view override returns (uint32 domain) {} + + function getTippyTopHatDomain( + uint32 _topHatDomain + ) external view override returns (uint32 domain) {} + + function noCircularLinkage( + uint32 _topHatDomain, + uint256 _linkedAdmin + ) external view override returns (bool notCircular) {} + + function sameTippyTopHatDomain( + uint32 _topHatDomain, + uint256 _newAdminHat + ) external view override returns (bool sameDomain) {} + + function batchCreateHats( + uint256[] calldata _admins, + string[] calldata _details, + uint32[] calldata _maxSupplies, + address[] memory _eligibilityModules, + address[] memory _toggleModules, + bool[] calldata _mutables, + string[] calldata _imageURIs + ) external override returns (bool success) {} + + function getNextId( + uint256 + ) external view override returns (uint256 nextId) { + nextId = hatId; + } + + function batchMintHats( + uint256[] calldata _hatIds, + address[] calldata _wearers + ) external override returns (bool success) {} + + function setHatStatus( + uint256 _hatId, + bool _newStatus + ) external override returns (bool toggled) {} + + function checkHatStatus( + uint256 _hatId + ) external override returns (bool toggled) {} - function getNextId(uint256) external view returns (uint256 nextId) { - nextId = count; + function setHatWearerStatus( + uint256 _hatId, + address _wearer, + bool _eligible, + bool _standing + ) external override returns (bool updated) {} + + function checkHatWearerStatus( + uint256 _hatId, + address + ) external override returns (bool updated) { + // 'burns' the hat if the wearer is no longer eligible + wearers[_hatId] = address(0); + return true; } + + function renounceHat(uint256 _hatId) external override {} + + function makeHatImmutable(uint256 _hatId) external override {} + + function changeHatDetails( + uint256 _hatId, + string memory _newDetails + ) external override {} + + function changeHatToggle( + uint256 _hatId, + address _newToggle + ) external override {} + + function changeHatImageURI( + uint256 _hatId, + string memory _newImageURI + ) external override {} + + function changeHatMaxSupply( + uint256 _hatId, + uint32 _newMaxSupply + ) external override {} + + function requestLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat + ) external override {} + + function approveLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external override {} + + function unlinkTopHatFromTree( + uint32 _topHatId, + address _wearer + ) external override {} + + function relinkTopHatWithinTree( + uint32 _topHatDomain, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external override {} + + function viewHat( + uint256 _hatId + ) + external + view + override + returns ( + string memory _details, + uint32 _maxSupply, + uint32 _supply, + address _eligibility, + address _toggle, + string memory _imageURI, + uint16 _lastHatId, + bool _mutable, + bool _active + ) + {} + + function isAdminOfHat( + address _user, + uint256 _hatId + ) external view override returns (bool isAdmin) {} + + function isInGoodStanding( + address _wearer, + uint256 _hatId + ) external view override returns (bool standing) {} + + function isEligible( + address _wearer, + uint256 _hatId + ) external view override returns (bool eligible) {} + + function getHatToggleModule( + uint256 _hatId + ) external view override returns (address toggle) {} + + function getHatMaxSupply( + uint256 _hatId + ) external view override returns (uint32 maxSupply) {} + + function hatSupply( + uint256 _hatId + ) external view override returns (uint32 supply) {} + + function getImageURIForHat( + uint256 _hatId + ) external view override returns (string memory _uri) {} + + function balanceOf( + address _wearer, + uint256 _hatId + ) external view override returns (uint256 balance) {} + + function balanceOfBatch( + address[] calldata _wearers, + uint256[] calldata _hatIds + ) external view override returns (uint256[] memory) {} + + function uri( + uint256 id + ) external view override returns (string memory _uri) {} } diff --git a/contracts/mocks/MockHatsAdmin.sol b/contracts/mocks/MockHatsAdmin.sol deleted file mode 100644 index bddb1368..00000000 --- a/contracts/mocks/MockHatsAdmin.sol +++ /dev/null @@ -1,284 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -import {IHats} from "../interfaces/hats/full/IHats.sol"; - -contract MockHatsAutoAdmin is IHats { - uint256 hatId = 0; - mapping(uint256 => address) public wearer; - mapping(uint256 => address) public eligibility; - - event HatCreated(uint256 hatId); - - function mintTopHat( - address, - string memory, - string memory - ) external pure returns (uint256 topHatId) { - return 0; - } - - function createHat( - uint256, - string calldata, - uint32, - address _eligibility, - address, - bool, - string calldata - ) external returns (uint256 newHatId) { - hatId++; - eligibility[hatId] = _eligibility; - emit HatCreated(hatId); - return hatId; - } - - function mintHat( - uint256 _hatId, - address _wearer - ) external returns (bool success) { - wearer[_hatId] = _wearer; - return true; - } - - function isWearerOfHat( - address _wearer, - uint256 _hatId - ) external view override returns (bool) { - return _wearer == wearer[_hatId]; - } - - function getHatEligibilityModule( - uint256 _hatId - ) external view override returns (address) { - return eligibility[_hatId]; - } - - function transferHat( - uint256 _hatId, - address, - address to - ) external override { - wearer[_hatId] = to; - } - - function changeHatEligibility( - uint256 _hatId, - address _newEligibility - ) external override { - eligibility[_hatId] = _newEligibility; - } - - function buildHatId( - uint256 _admin, - uint16 _newHat - ) external pure override returns (uint256 id) {} - - function getHatLevel( - uint256 _hatId - ) external view override returns (uint32 level) {} - - function getLocalHatLevel( - uint256 _hatId - ) external pure override returns (uint32 level) {} - - function isTopHat( - uint256 _hatId - ) external view override returns (bool _topHat) {} - - function isLocalTopHat( - uint256 _hatId - ) external pure override returns (bool _localTopHat) {} - - function isValidHatId( - uint256 _hatId - ) external view override returns (bool validHatId) {} - - function getAdminAtLevel( - uint256 _hatId, - uint32 _level - ) external view override returns (uint256 admin) {} - - function getAdminAtLocalLevel( - uint256 _hatId, - uint32 _level - ) external pure override returns (uint256 admin) {} - - function getTopHatDomain( - uint256 _hatId - ) external view override returns (uint32 domain) {} - - function getTippyTopHatDomain( - uint32 _topHatDomain - ) external view override returns (uint32 domain) {} - - function noCircularLinkage( - uint32 _topHatDomain, - uint256 _linkedAdmin - ) external view override returns (bool notCircular) {} - - function sameTippyTopHatDomain( - uint32 _topHatDomain, - uint256 _newAdminHat - ) external view override returns (bool sameDomain) {} - - function batchCreateHats( - uint256[] calldata _admins, - string[] calldata _details, - uint32[] calldata _maxSupplies, - address[] memory _eligibilityModules, - address[] memory _toggleModules, - bool[] calldata _mutables, - string[] calldata _imageURIs - ) external override returns (bool success) {} - - function getNextId( - uint256 _admin - ) external view override returns (uint256 nextId) {} - - function batchMintHats( - uint256[] calldata _hatIds, - address[] calldata _wearers - ) external override returns (bool success) {} - - function setHatStatus( - uint256 _hatId, - bool _newStatus - ) external override returns (bool toggled) {} - - function checkHatStatus( - uint256 _hatId - ) external override returns (bool toggled) {} - - function setHatWearerStatus( - uint256 _hatId, - address _wearer, - bool _eligible, - bool _standing - ) external override returns (bool updated) {} - - function checkHatWearerStatus( - uint256 _hatId, - address - ) external override returns (bool updated) { - // 'burns' the hat if the wearer is no longer eligible - wearer[_hatId] = address(0); - return true; - } - - function renounceHat(uint256 _hatId) external override {} - - function makeHatImmutable(uint256 _hatId) external override {} - - function changeHatDetails( - uint256 _hatId, - string memory _newDetails - ) external override {} - - function changeHatToggle( - uint256 _hatId, - address _newToggle - ) external override {} - - function changeHatImageURI( - uint256 _hatId, - string memory _newImageURI - ) external override {} - - function changeHatMaxSupply( - uint256 _hatId, - uint32 _newMaxSupply - ) external override {} - - function requestLinkTopHatToTree( - uint32 _topHatId, - uint256 _newAdminHat - ) external override {} - - function approveLinkTopHatToTree( - uint32 _topHatId, - uint256 _newAdminHat, - address _eligibility, - address _toggle, - string calldata _details, - string calldata _imageURI - ) external override {} - - function unlinkTopHatFromTree( - uint32 _topHatId, - address _wearer - ) external override {} - - function relinkTopHatWithinTree( - uint32 _topHatDomain, - uint256 _newAdminHat, - address _eligibility, - address _toggle, - string calldata _details, - string calldata _imageURI - ) external override {} - - function viewHat( - uint256 _hatId - ) - external - view - override - returns ( - string memory _details, - uint32 _maxSupply, - uint32 _supply, - address _eligibility, - address _toggle, - string memory _imageURI, - uint16 _lastHatId, - bool _mutable, - bool _active - ) - {} - - function isAdminOfHat( - address _user, - uint256 _hatId - ) external view override returns (bool isAdmin) {} - - function isInGoodStanding( - address _wearer, - uint256 _hatId - ) external view override returns (bool standing) {} - - function isEligible( - address _wearer, - uint256 _hatId - ) external view override returns (bool eligible) {} - - function getHatToggleModule( - uint256 _hatId - ) external view override returns (address toggle) {} - - function getHatMaxSupply( - uint256 _hatId - ) external view override returns (uint32 maxSupply) {} - - function hatSupply( - uint256 _hatId - ) external view override returns (uint32 supply) {} - - function getImageURIForHat( - uint256 _hatId - ) external view override returns (string memory _uri) {} - - function balanceOf( - address _wearer, - uint256 _hatId - ) external view override returns (uint256 balance) {} - - function balanceOfBatch( - address[] calldata _wearers, - uint256[] calldata _hatIds - ) external view override returns (uint256[] memory) {} - - function uri( - uint256 id - ) external view override returns (string memory _uri) {} -} diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index 7061b1ac..c19a5db8 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -4,8 +4,8 @@ import hre from 'hardhat'; import { DecentAutonomousAdmin, DecentAutonomousAdmin__factory, - MockHatsAutoAdmin, - MockHatsAutoAdmin__factory, + MockHats, + MockHats__factory, MockHatsElectionEligibility, MockHatsElectionEligibility__factory, } from '../typechain-types'; @@ -18,7 +18,7 @@ describe('DecentAutonomousAdminHat', function () { let nominatedWearer: SignerWithAddress; // Contract instances - let hatsProtocol: MockHatsAutoAdmin; + let hatsProtocol: MockHats; let hatsElectionModule: MockHatsElectionEligibility; let adminHat: DecentAutonomousAdmin; @@ -30,14 +30,14 @@ describe('DecentAutonomousAdminHat', function () { [deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners(); // Deploy MockHatsAutoAdmin (Mock Hats Protocol) - hatsProtocol = await new MockHatsAutoAdmin__factory(deployer).deploy(); + hatsProtocol = await new MockHats__factory(deployer).deploy(); // Deploy MockHatsElectionEligibility (Eligibility Module) hatsElectionModule = await new MockHatsElectionEligibility__factory(deployer).deploy(); // Create Admin Hat const createAdminTx = await hatsProtocol.createHat( - await hatsProtocol.getAddress(), // Admin address (self-administered) + hre.ethers.ZeroAddress, // Admin address (self-administered), currently unused 'Details', // Hat details 100, // Max supply hre.ethers.ZeroAddress, // Eligibility module (none) @@ -56,7 +56,7 @@ describe('DecentAutonomousAdminHat', function () { // Create User Hat under the admin hat const createUserTx = await hatsProtocol.createHat( - adminHatAddress, // Admin address (adminHat contract) + hre.ethers.ZeroAddress, // Admin address (adminHat contract), currently unused 'Details', // Hat details 100, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) @@ -76,10 +76,9 @@ describe('DecentAutonomousAdminHat', function () { it('should correctly validate current wearer and transfer', async function () { const args = { currentWearer: currentWearer.address, - userHatProtocol: await hatsProtocol.getAddress(), - userHatId: userHatId, + hatsProtocol: await hatsProtocol.getAddress(), + hatId: userHatId, nominatedWearer: nominatedWearer.address, - sablierStreamInfo: [], // No Sablier stream info for this test }; // Call triggerStartNextTerm on the adminHat contract @@ -93,8 +92,8 @@ describe('DecentAutonomousAdminHat', function () { it('should correctly invalidate random address as current wearer', async function () { const args = { currentWearer: randomUser.address, - userHatProtocol: await hatsProtocol.getAddress(), - userHatId: userHatId, + hatsProtocol: await hatsProtocol.getAddress(), + hatId: userHatId, nominatedWearer: nominatedWearer.address, sablierStreamInfo: [], // No Sablier stream info for this test }; diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index 56fdcbe8..c35f9568 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -10,13 +10,13 @@ import { DecentHats__factory, KeyValuePairs, KeyValuePairs__factory, - MockHats__factory, ERC6551Registry__factory, MockHatsAccount__factory, ERC6551Registry, DecentHats, MockHatsAccount, MockHats, + MockHats__factory, MockSablierV2LockupLinear__factory, MockSablierV2LockupLinear, MockERC20__factory, @@ -300,18 +300,16 @@ describe('DecentHats', () => { describe('Creating Hats Accounts', () => { it('Generates the correct Addresses for the current Hats', async () => { - const currentCount = await mockHats.count(); - + const currentCount = await mockHats.hatId(); for (let i = 0n; i < currentCount; i++) { - const topHatAccount = await getHatAccount( + const hatAccount = await getHatAccount( i, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, ); - - expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); + expect(await hatAccount.tokenId()).eq(i); + expect(await hatAccount.tokenImplementation()).eq(mockHatsAddress); } }); }); @@ -813,12 +811,12 @@ describe('DecentHats', () => { // First transfer the top hat to the Safe await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); - const hatsCountBeforeCreate = await mockHats.count(); + const hatsCountBeforeCreate = await mockHats.hatId(); expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat await createRoleHatPromise; - const newHatId = await mockHats.count(); + const newHatId = await mockHats.hatId(); expect(newHatId).to.equal(3); // + newly created hat }); }); @@ -957,12 +955,12 @@ describe('DecentHats', () => { // First transfer the top hat to the Safe await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); - const hatsCountBeforeCreate = await mockHats.count(); + const hatsCountBeforeCreate = await mockHats.hatId(); expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat await createRoleHatPromise; - const newHatId = await mockHats.count(); + const newHatId = await mockHats.hatId(); expect(newHatId).to.equal(3); // + newly created hat }); }); diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index dd9a3654..194049ef 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -254,7 +254,7 @@ describe('DecentHats_0_1_0', () => { describe('Creating Hats Accounts', () => { it('Generates the correct Addresses for the current Hats', async () => { - const currentCount = await mockHats.count(); + const currentCount = await mockHats.hatId(); for (let i = 0n; i < currentCount; i++) { const topHatAccount = await getHatAccount( @@ -621,12 +621,12 @@ describe('DecentHats_0_1_0', () => { // First transfer the top hat to the Safe await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); - const hatsCountBeforeCreate = await mockHats.count(); + const hatsCountBeforeCreate = await mockHats.hatId(); expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat await createRoleHatPromise; - const newHatId = await mockHats.count(); + const newHatId = await mockHats.hatId(); expect(newHatId).to.equal(3); // + newly created hat }); }); From ba608297a2f98e52155b842aab939a6b6c727ec3 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 29 Oct 2024 13:07:22 -0400 Subject: [PATCH 145/206] Update test name --- test/DecentHats.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index c35f9568..15cdaad9 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -821,7 +821,7 @@ describe('DecentHats', () => { }); }); - describe('Creating a new hat on existing Tree', () => { + describe('Creating a new Termed hat on existing tree', () => { let createRoleHatPromise: Promise; const topHatId = 0; From 3d771f487726706a65cb77ba73312d0831412ad7 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:31:29 -0400 Subject: [PATCH 146/206] review feedback --- contracts/DecentHats.sol | 30 ++++---- test/DecentHats.test.ts | 146 ++++++++++++++++++--------------------- 2 files changed, 81 insertions(+), 95 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 52159e22..408ab7d0 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -30,7 +30,7 @@ contract DecentHats { bool transferable; } - struct TermedParams { + struct TermedParam { uint128 termEndDateTs; address[] nominatedWearers; } @@ -40,10 +40,9 @@ contract DecentHats { string details; string imageURI; SablierStreamParams[] sablierParams; - TermedParams[] termedParams; + TermedParam termedParam; uint32 maxSupply; bool isMutable; - bool isTermed; } struct CreateTreeParams { @@ -127,7 +126,8 @@ contract DecentHats { ); for (uint256 i = 0; i < params.hats.length; ) { - if (params.hats[i].isTermed) { + // {assuption} if 0 nominatedWearers, then it is not a termed role + if (params.hats[i].termedParam.nominatedWearers.length > 0) { // Create election module and set as eligiblity _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, @@ -137,7 +137,7 @@ contract DecentHats { params.hatsElectionEligibilityImplementation, params.hatsProtocol.getNextId(adminHatId), topHatId, - params.hats[i].termedParams[0] + params.hats[i].termedParam ), adminHatId, params.hats[i] @@ -225,7 +225,7 @@ contract DecentHats { params.hatsElectionEligibilityImplementation, params.hatsProtocol.getNextId(params.adminHatId), params.topHatId, - params.hat.termedParams[0] + params.hat.termedParam ), params.adminHatId, params.hat @@ -359,11 +359,7 @@ contract DecentHats { Hat calldata hat ) internal { require( - hat.termedParams.length == 1, - "DecentHats: termedParams length must be 1" - ); - require( - hat.termedParams[0].nominatedWearers.length == 1, + hat.termedParam.nominatedWearers.length == 1, "DecentHats: nominatedWearers length must be 1" ); uint256 hatId = _createHat( @@ -375,16 +371,16 @@ contract DecentHats { ); IHatsElectionEligibility(eligibilityAddress).elect( - hat.termedParams[0].termEndDateTs, - hat.termedParams[0].nominatedWearers + hat.termedParam.termEndDateTs, + hat.termedParam.nominatedWearers ); - hatsProtocol.mintHat(hatId, hat.termedParams[0].nominatedWearers[0]); + hatsProtocol.mintHat(hatId, hat.termedParam.nominatedWearers[0]); for (uint256 i = 0; i < hat.sablierParams.length; ) { _createSablierStream( hat.sablierParams[i], - hat.termedParams[0].nominatedWearers[0] + hat.termedParam.nominatedWearers[0] ); unchecked { ++i; @@ -432,13 +428,13 @@ contract DecentHats { address hatsElectionEligibilityImplementation, uint256 hatId, uint256 topHatId, - TermedParams calldata termedParams + TermedParam calldata termedParam ) internal returns (address electionModuleAddress) { electionModuleAddress = hatsModuleFactory.createHatsModule( hatsElectionEligibilityImplementation, hatId, abi.encode(topHatId, uint256(0)), - abi.encode(termedParams.termEndDateTs), + abi.encode(termedParam.termEndDateTs), uint256(SALT) ); } diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index 15cdaad9..3cd4b795 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -184,8 +184,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -195,8 +197,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, { maxSupply: 1, @@ -205,8 +209,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -262,13 +268,11 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hats: [], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -337,11 +341,13 @@ describe('DecentHats', () => { maxSupply: 1, details: '', imageURI: '', - isMutable: false, + isMutable: true, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -351,13 +357,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: true, - termedParams: [ - { - termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], - }, - ], + termedParam: { + termEndDateTs: BigInt(Date.now() + 100000), + nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], + }, }, { maxSupply: 1, @@ -366,13 +369,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: true, - termedParams: [ - { - termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], - }, - ], + termedParam: { + termEndDateTs: BigInt(Date.now() + 100000), + nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], + }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -431,13 +431,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -462,13 +459,10 @@ describe('DecentHats', () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], - isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, { maxSupply: 1, @@ -477,13 +471,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -573,13 +564,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hats: [ { @@ -618,13 +606,10 @@ describe('DecentHats', () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], - isTermed: false, - termedParams: [ - { - termEndDateTs: 0, - nominatedWearers: [], - }, - ], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -711,8 +696,10 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [], + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: @@ -750,8 +737,11 @@ describe('DecentHats', () => { imageURI: '', isMutable: true, wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - isTermed: false, - termedParams: [], + + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, sablierParams: [ { sablier: mockSablierAddress, @@ -847,8 +837,11 @@ describe('DecentHats', () => { isMutable: false, wearer: ethers.ZeroAddress, sablierParams: [], - isTermed: false, - termedParams: [], + + termedParam: { + termEndDateTs: 0, + nominatedWearers: [], + }, }, hatsModuleFactory: mockHatsModuleFactoryAddress, hatsElectionEligibilityImplementation: @@ -889,13 +882,10 @@ describe('DecentHats', () => { imageURI: '', isMutable: true, wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - isTermed: true, - termedParams: [ - { - termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearers: ['0xdce7ca0555101f97451926944f5ae3b7adb2f5ae'], - }, - ], + termedParam: { + termEndDateTs: BigInt(Date.now() + 100000), + nominatedWearers: ['0xdce7ca0555101f97451926944f5ae3b7adb2f5ae'], + }, sablierParams: [ { sablier: mockSablierAddress, From 4a93ed05a6422d4472b96eb46b3f241824c84134 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 29 Oct 2024 13:44:34 -0400 Subject: [PATCH 147/206] nominatedWearer now a single address to match business logic --- contracts/DecentHats.sol | 16 +++++++--------- test/DecentHats.test.ts | 32 ++++++++++++++++---------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 408ab7d0..04d03b2d 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -32,7 +32,7 @@ contract DecentHats { struct TermedParam { uint128 termEndDateTs; - address[] nominatedWearers; + address nominatedWearer; } struct Hat { @@ -127,7 +127,7 @@ contract DecentHats { for (uint256 i = 0; i < params.hats.length; ) { // {assuption} if 0 nominatedWearers, then it is not a termed role - if (params.hats[i].termedParam.nominatedWearers.length > 0) { + if (params.hats[i].termedParam.nominatedWearer != address(0)) { // Create election module and set as eligiblity _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, @@ -358,10 +358,6 @@ contract DecentHats { uint256 adminHatId, Hat calldata hat ) internal { - require( - hat.termedParam.nominatedWearers.length == 1, - "DecentHats: nominatedWearers length must be 1" - ); uint256 hatId = _createHat( hatsProtocol, adminHatId, @@ -370,17 +366,19 @@ contract DecentHats { eligibilityAddress ); + address[] memory nominatedWearers = new address[](1); + nominatedWearers[0] = hat.termedParam.nominatedWearer; IHatsElectionEligibility(eligibilityAddress).elect( hat.termedParam.termEndDateTs, - hat.termedParam.nominatedWearers + nominatedWearers ); - hatsProtocol.mintHat(hatId, hat.termedParam.nominatedWearers[0]); + hatsProtocol.mintHat(hatId, hat.termedParam.nominatedWearer); for (uint256 i = 0; i < hat.sablierParams.length; ) { _createSablierStream( hat.sablierParams[i], - hat.termedParam.nominatedWearers[0] + hat.termedParam.nominatedWearer ); unchecked { ++i; diff --git a/test/DecentHats.test.ts b/test/DecentHats.test.ts index 3cd4b795..802ca10c 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHats.test.ts @@ -186,7 +186,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hats: [ @@ -199,7 +199,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, { @@ -211,7 +211,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, ], @@ -271,7 +271,7 @@ describe('DecentHats', () => { termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hats: [], @@ -346,7 +346,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hats: [ @@ -359,7 +359,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], + nominatedWearer: '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', }, }, { @@ -371,7 +371,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearers: ['0x14dC79964da2C08b23698B3D3cc7Ca32193d9955'], + nominatedWearer: '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', }, }, ], @@ -433,7 +433,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hats: [ @@ -461,7 +461,7 @@ describe('DecentHats', () => { ], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, { @@ -473,7 +473,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, ], @@ -566,7 +566,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hats: [ @@ -608,7 +608,7 @@ describe('DecentHats', () => { ], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, ], @@ -698,7 +698,7 @@ describe('DecentHats', () => { sablierParams: [], termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -740,7 +740,7 @@ describe('DecentHats', () => { termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, sablierParams: [ { @@ -840,7 +840,7 @@ describe('DecentHats', () => { termedParam: { termEndDateTs: 0, - nominatedWearers: [], + nominatedWearer: ethers.ZeroAddress, }, }, hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -884,7 +884,7 @@ describe('DecentHats', () => { wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', termedParam: { termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearers: ['0xdce7ca0555101f97451926944f5ae3b7adb2f5ae'], + nominatedWearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', }, sablierParams: [ { From aa4d6a672efaacafc09c3a0b2e10487078423a85 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 29 Oct 2024 13:45:31 -0400 Subject: [PATCH 148/206] Remove NAME from contract --- contracts/DecentHats.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 04d03b2d..bdc89631 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -15,7 +15,6 @@ import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProx import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; contract DecentHats { - string public constant NAME = "DecentHats"; bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; From d18ad255d7dd314a2afebd840d78bf19f4a03ceb Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 29 Oct 2024 13:46:41 -0400 Subject: [PATCH 149/206] Remove unused import --- contracts/DecentHats.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index bdc89631..2912dada 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -8,7 +8,6 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/full/IHats.sol"; import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; -import {DecentAutonomousAdmin} from "./DecentAutonomousAdmin.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; From 1c0c3b95b8bc50009927c607e9bd189d48d2a170 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:58:37 -0400 Subject: [PATCH 150/206] use error and revert --- contracts/DecentAutonomousAdmin.sol | 11 ++++------- contracts/interfaces/IDecentAutonomousAdmin.sol | 1 + 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 07c38c97..37bf73fb 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -21,13 +21,10 @@ contract DecentAutonomousAdmin is // Public Functions // ////////////////////////////////////////////////////////////// function triggerStartNextTerm(TriggerStartArgs calldata args) public { - require( - args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId), - "Not current wearer" - ); - address hatsEligibilityModuleAddress = args - .hatsProtocol - .getHatEligibilityModule(args.hatId); + if ( + args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId) == + false + ) revert NotCurrentWearer(); IHatsElectionEligibility hatsElectionModule = IHatsElectionEligibility( hatsEligibilityModuleAddress diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentAutonomousAdmin.sol index affa38bf..2591b02e 100644 --- a/contracts/interfaces/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/IDecentAutonomousAdmin.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.28; import {IHats} from "./hats/full/IHats.sol"; interface IDecentAutonomousAdmin { + error NotCurrentWearer(); struct TriggerStartArgs { address currentWearer; IHats hatsProtocol; From 4ffbbe7911ff8b852b94a9f869771248a080e875 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:58:59 -0400 Subject: [PATCH 151/206] remove declaration and pass directly --- contracts/DecentAutonomousAdmin.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 37bf73fb..36bdf039 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -27,7 +27,7 @@ contract DecentAutonomousAdmin is ) revert NotCurrentWearer(); IHatsElectionEligibility hatsElectionModule = IHatsElectionEligibility( - hatsEligibilityModuleAddress + args.hatsProtocol.getHatEligibilityModule(args.hatId) ); hatsElectionModule.startNextTerm(); From eaea6021ee65338121751386589b18d8e21deb16 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:34:56 -0400 Subject: [PATCH 152/206] remove _createHat internal func and call directly --- contracts/DecentHats.sol | 49 +++++++++++++++------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 2912dada..df2b3595 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -261,25 +261,6 @@ contract DecentHats { ); } - function _createHat( - IHats _hatsProtocol, - uint256 adminHatId, - Hat memory _hat, - address toggle, - address eligibility - ) internal returns (uint256) { - return - _hatsProtocol.createHat( - adminHatId, - _hat.details, - _hat.maxSupply, - eligibility, - toggle, - _hat.isMutable, - _hat.imageURI - ); - } - function _createAccount( IERC6551Registry _registry, address _hatsAccountImplementation, @@ -325,12 +306,14 @@ contract DecentHats { uint256 adminHatId, Hat calldata hat ) internal returns (uint256 hatId, address accountAddress) { - hatId = _createHat( - hatsProtocol, + hatId = hatsProtocol.createHat( adminHatId, - hat, + hat.details, + hat.maxSupply, topHatAccount, - topHatAccount + topHatAccount, + hat.isMutable, + hat.imageURI ); accountAddress = _createAccount( registry, @@ -356,12 +339,14 @@ contract DecentHats { uint256 adminHatId, Hat calldata hat ) internal { - uint256 hatId = _createHat( - hatsProtocol, + uint256 hatId = hatsProtocol.createHat( adminHatId, - hat, + hat.details, + hat.maxSupply, + eligibilityAddress, topHatAccount, - eligibilityAddress + hat.isMutable, + hat.imageURI ); address[] memory nominatedWearers = new address[](1); @@ -394,12 +379,14 @@ contract DecentHats { uint256 topHatId, Hat calldata hat ) internal returns (uint256 adminHatId, address accountAddress) { - adminHatId = _createHat( - hatsProtocol, + adminHatId = hatsProtocol.createHat( topHatId, - hat, + hat.details, + hat.maxSupply, + topHatAccount, topHatAccount, - topHatAccount + hat.isMutable, + hat.imageURI ); accountAddress = _createAccount( From 59e2c6bd261b170c442548ca96db5370f89569ab Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:41:18 -0400 Subject: [PATCH 153/206] remove _createElectionEligiblityModule and use function call directly --- contracts/DecentHats.sol | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index df2b3595..6dc8c833 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -130,12 +130,12 @@ contract DecentHats { _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, topHatAccount, - _createElectionEligiblityModule( - params.hatsModuleFactory, + params.hatsModuleFactory.createHatsModule( params.hatsElectionEligibilityImplementation, params.hatsProtocol.getNextId(adminHatId), - topHatId, - params.hats[i].termedParam + abi.encode(topHatId, uint256(0)), + abi.encode(params.hats[i].termedParam.termEndDateTs), + uint256(SALT) ), adminHatId, params.hats[i] @@ -218,12 +218,12 @@ contract DecentHats { _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, params.topHatAccount, - _createElectionEligiblityModule( - params.hatsModuleFactory, + params.hatsModuleFactory.createHatsModule( params.hatsElectionEligibilityImplementation, params.hatsProtocol.getNextId(params.adminHatId), - params.topHatId, - params.hat.termedParam + abi.encode(params.topHatId, uint256(0)), + abi.encode(params.hat.termedParam.termEndDateTs), + uint256(SALT) ), params.adminHatId, params.hat @@ -406,22 +406,6 @@ contract DecentHats { ); } - function _createElectionEligiblityModule( - IHatsModuleFactory hatsModuleFactory, - address hatsElectionEligibilityImplementation, - uint256 hatId, - uint256 topHatId, - TermedParam calldata termedParam - ) internal returns (address electionModuleAddress) { - electionModuleAddress = hatsModuleFactory.createHatsModule( - hatsElectionEligibilityImplementation, - hatId, - abi.encode(topHatId, uint256(0)), - abi.encode(termedParam.termEndDateTs), - uint256(SALT) - ); - } - function _createSablierStream( SablierStreamParams memory sablierParams, address recipient From 21fca7f0907498005d8cf0cacdd86144663c6589 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:43:55 -0400 Subject: [PATCH 154/206] remove _createAccount and use function call directly --- contracts/DecentHats.sol | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 6dc8c833..510061a3 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -261,22 +261,6 @@ contract DecentHats { ); } - function _createAccount( - IERC6551Registry _registry, - address _hatsAccountImplementation, - address protocolAddress, - uint256 hatId - ) internal returns (address) { - return - _registry.createAccount( - _hatsAccountImplementation, - SALT, - block.chainid, - protocolAddress, - hatId - ); - } - function _createTopHatAndAccount( IHats _hatsProtocol, string memory _topHatDetails, @@ -290,9 +274,10 @@ contract DecentHats { _topHatImageURI ); - topHatAccount = _createAccount( - _registry, + topHatAccount = _registry.createAccount( _hatsAccountImplementation, + SALT, + block.chainid, address(_hatsProtocol), topHatId ); @@ -315,9 +300,11 @@ contract DecentHats { hat.isMutable, hat.imageURI ); - accountAddress = _createAccount( - registry, + + accountAddress = registry.createAccount( hatsAccountImplementation, + SALT, + block.chainid, address(hatsProtocol), hatId ); @@ -389,9 +376,10 @@ contract DecentHats { hat.imageURI ); - accountAddress = _createAccount( - registry, + accountAddress = registry.createAccount( hatsAccountImplementation, + SALT, + block.chainid, address(hatsProtocol), adminHatId ); From 622cb0980402d57c0276bb35765b82992c9c7276 Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:46:58 -0400 Subject: [PATCH 155/206] add comments --- contracts/DecentHats.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/DecentHats.sol b/contracts/DecentHats.sol index 510061a3..5d133793 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHats.sol @@ -130,10 +130,10 @@ contract DecentHats { _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, topHatAccount, - params.hatsModuleFactory.createHatsModule( + params.hatsModuleFactory.createHatsModule( // Create election module and set as eligibility params.hatsElectionEligibilityImplementation, params.hatsProtocol.getNextId(adminHatId), - abi.encode(topHatId, uint256(0)), + abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] abi.encode(params.hats[i].termedParam.termEndDateTs), uint256(SALT) ), @@ -218,10 +218,10 @@ contract DecentHats { _createTermedHatAndAccountAndMintAndStreams( params.hatsProtocol, params.topHatAccount, - params.hatsModuleFactory.createHatsModule( + params.hatsModuleFactory.createHatsModule( // Create election module and set as eligibility params.hatsElectionEligibilityImplementation, params.hatsProtocol.getNextId(params.adminHatId), - abi.encode(params.topHatId, uint256(0)), + abi.encode(params.topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] abi.encode(params.hat.termedParam.termEndDateTs), uint256(SALT) ), From b02cbe20834cb7de04abae1ccc8af8343ed3175f Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:52:42 -0400 Subject: [PATCH 156/206] update to customError for test --- test/DecentAutonomousAdmin.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index c19a5db8..c29abb52 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -99,9 +99,9 @@ describe('DecentAutonomousAdminHat', function () { }; // revert if not the current wearer - await expect(adminHat.connect(randomUser).triggerStartNextTerm(args)).to.be.revertedWith( - 'Not current wearer', - ); + await expect( + adminHat.connect(randomUser).triggerStartNextTerm(args), + ).to.be.revertedWithCustomError(adminHat, 'NotCurrentWearer'); }); }); }); From 1dbf281b46a4f6619160451ee05a8aaa1513309c Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:53:57 -0400 Subject: [PATCH 157/206] update name to make sense --- test/DecentAutonomousAdmin.test.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index c29abb52..a20b00a0 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -20,7 +20,7 @@ describe('DecentAutonomousAdminHat', function () { // Contract instances let hatsProtocol: MockHats; let hatsElectionModule: MockHatsElectionEligibility; - let adminHat: DecentAutonomousAdmin; + let decentAutonomousAdminInstance: DecentAutonomousAdmin; // Variables let userHatId: bigint; @@ -49,14 +49,14 @@ describe('DecentAutonomousAdminHat', function () { const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0]; // Deploy DecentAutonomousAdminHat contract with the admin hat ID - adminHat = await new DecentAutonomousAdmin__factory(deployer).deploy(); - const adminHatAddress = await adminHat.getAddress(); + decentAutonomousAdminInstance = await new DecentAutonomousAdmin__factory(deployer).deploy(); + const adminHatAddress = await decentAutonomousAdminInstance.getAddress(); // Mint the admin hat to adminHatWearer await hatsProtocol.mintHat(adminHatId, adminHatAddress); // Create User Hat under the admin hat const createUserTx = await hatsProtocol.createHat( - hre.ethers.ZeroAddress, // Admin address (adminHat contract), currently unused + hre.ethers.ZeroAddress, // Admin address (decentAutonomousAdminInstance contract), currently unused 'Details', // Hat details 100, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) @@ -81,8 +81,8 @@ describe('DecentAutonomousAdminHat', function () { nominatedWearer: nominatedWearer.address, }; - // Call triggerStartNextTerm on the adminHat contract - await adminHat.triggerStartNextTerm(args); + // Call triggerStartNextTerm on the decentAutonomousAdminInstance contract + await decentAutonomousAdminInstance.triggerStartNextTerm(args); // Verify the hat is now worn by the nominated wearer expect((await hatsProtocol.isWearerOfHat(nominatedWearer.address, userHatId)) === true); @@ -100,8 +100,8 @@ describe('DecentAutonomousAdminHat', function () { // revert if not the current wearer await expect( - adminHat.connect(randomUser).triggerStartNextTerm(args), - ).to.be.revertedWithCustomError(adminHat, 'NotCurrentWearer'); + decentAutonomousAdminInstance.connect(randomUser).triggerStartNextTerm(args), + ).to.be.revertedWithCustomError(decentAutonomousAdminInstance, 'NotCurrentWearer'); }); }); }); From 68f6730d7d75ce3e56ef31884f381254da1637b2 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 10:06:39 -0400 Subject: [PATCH 158/206] Rename contract to DecentHatsCreationModule --- ...tHats.sol => DecentHatsCreationModule.sol} | 2 +- ...st.ts => DecentHatsCreationModule.test.ts} | 92 ++++++++++--------- 2 files changed, 51 insertions(+), 43 deletions(-) rename contracts/{DecentHats.sol => DecentHatsCreationModule.sol} (99%) rename test/{DecentHats.test.ts => DecentHatsCreationModule.test.ts} (93%) diff --git a/contracts/DecentHats.sol b/contracts/DecentHatsCreationModule.sol similarity index 99% rename from contracts/DecentHats.sol rename to contracts/DecentHatsCreationModule.sol index 5d133793..ad3fa4a3 100644 --- a/contracts/DecentHats.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -13,7 +13,7 @@ import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionElig import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; -contract DecentHats { +contract DecentHatsCreationModule { bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; diff --git a/test/DecentHats.test.ts b/test/DecentHatsCreationModule.test.ts similarity index 93% rename from test/DecentHats.test.ts rename to test/DecentHatsCreationModule.test.ts index 802ca10c..2f6d5956 100644 --- a/test/DecentHats.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -7,13 +7,13 @@ import hre from 'hardhat'; import { GnosisSafeL2, GnosisSafeL2__factory, - DecentHats__factory, + DecentHatsCreationModule__factory, KeyValuePairs, KeyValuePairs__factory, ERC6551Registry__factory, MockHatsAccount__factory, ERC6551Registry, - DecentHats, + DecentHatsCreationModule, MockHatsAccount, MockHats, MockHats__factory, @@ -41,8 +41,8 @@ describe('DecentHats', () => { let keyValuePairs: KeyValuePairs; let gnosisSafe: GnosisSafeL2; - let decentHats: DecentHats; - let decentHatsAddress: string; + let decentHatsCreationModule: DecentHatsCreationModule; + let decentHatsCreationModuleAddress: string; let gnosisSafeAddress: string; let erc6551Registry: ERC6551Registry; @@ -82,8 +82,8 @@ describe('DecentHats', () => { erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHats__factory(deployer).deploy(); - decentHatsAddress = await decentHats.getAddress(); + decentHatsCreationModule = await new DecentHatsCreationModule__factory(deployer).deploy(); + decentHatsCreationModuleAddress = await decentHatsCreationModule.getAddress(); moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); @@ -144,7 +144,7 @@ describe('DecentHats', () => { to: gnosisSafeAddress, transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( 'enableModule', - [decentHatsAddress], + [decentHatsCreationModuleAddress], ), signers: [dao], }); @@ -155,7 +155,9 @@ describe('DecentHats', () => { }); it('Emits an EnabledModule event', async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, 'EnabledModule').withArgs(decentHatsAddress); + await expect(enableModuleTx) + .to.emit(gnosisSafe, 'EnabledModule') + .withArgs(decentHatsCreationModuleAddress); }); describe('Creating a new Top Hat and Tree', () => { @@ -164,8 +166,8 @@ describe('DecentHats', () => { beforeEach(async () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -232,7 +234,7 @@ describe('DecentHats', () => { it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); + .withArgs(decentHatsCreationModuleAddress); }); it('Emits some hatsTreeId ValueUpdated events', async () => { @@ -247,8 +249,8 @@ describe('DecentHats', () => { beforeEach(async () => { createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -292,7 +294,7 @@ describe('DecentHats', () => { it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx2) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); + .withArgs(decentHatsCreationModuleAddress); }); it('Creates Top Hats with sequential IDs', async () => { @@ -324,8 +326,8 @@ describe('DecentHats', () => { beforeEach(async () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -392,7 +394,7 @@ describe('DecentHats', () => { it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); + .withArgs(decentHatsCreationModuleAddress); }); it('Emits some hatsTreeId ValueUpdated events', async () => { @@ -411,8 +413,8 @@ describe('DecentHats', () => { createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -494,7 +496,7 @@ describe('DecentHats', () => { it('Emits an ExecutionFromModuleSuccess event', async () => { await expect(createAndDeclareTreeTx) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); + .withArgs(decentHatsCreationModuleAddress); }); it('Emits some hatsTreeId ValueUpdated events', async () => { @@ -544,8 +546,8 @@ describe('DecentHats', () => { await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -678,8 +680,8 @@ describe('DecentHats', () => { try { await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -720,8 +722,8 @@ describe('DecentHats', () => { createRoleHatPromise = executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createRoleHat', [ { @@ -772,23 +774,26 @@ describe('DecentHats', () => { it('Emits an ExecutionSuccess event', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); }); it('Emits an ExecutionFromModuleSuccess event', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); await expect(await createRoleHatPromise) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); + .withArgs(decentHatsCreationModuleAddress); }); it('Transfers the top hat back to the Safe', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); + const isModuleWearerOfTopHat = await mockHats.isWearerOfHat( + decentHatsCreationModuleAddress, + topHatId, + ); expect(isModuleWearerOfTopHat).to.equal(true); await createRoleHatPromise; @@ -799,7 +804,7 @@ describe('DecentHats', () => { it('Actually creates the new hat', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); const hatsCountBeforeCreate = await mockHats.hatId(); expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat @@ -819,8 +824,8 @@ describe('DecentHats', () => { try { await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { @@ -862,8 +867,8 @@ describe('DecentHats', () => { createRoleHatPromise = executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats__factory.createInterface().encodeFunctionData( + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createTermedRoleHat', [ { @@ -916,23 +921,26 @@ describe('DecentHats', () => { it('Emits an ExecutionSuccess event', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); }); it('Emits an ExecutionFromModuleSuccess event', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); await expect(await createRoleHatPromise) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); + .withArgs(decentHatsCreationModuleAddress); }); it('Transfers the top hat back to the Safe', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); + const isModuleWearerOfTopHat = await mockHats.isWearerOfHat( + decentHatsCreationModuleAddress, + topHatId, + ); expect(isModuleWearerOfTopHat).to.equal(true); await createRoleHatPromise; @@ -943,7 +951,7 @@ describe('DecentHats', () => { it('Actually creates the new hat', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); const hatsCountBeforeCreate = await mockHats.hatId(); expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat From 0c51fb075e1b9495c63264f3dcb585fe7702332d Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 10:08:04 -0400 Subject: [PATCH 159/206] Remove code for modifying an existing hats tree (adding a hat) --- contracts/DecentHatsCreationModule.sol | 77 ------- test/DecentHatsCreationModule.test.ts | 291 ------------------------- 2 files changed, 368 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index ad3fa4a3..d269a008 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -159,83 +159,6 @@ contract DecentHatsCreationModule { params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); } - /** - * @notice Creates a new role hat and any streams on it. - * - * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disabled after. - * - * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first - * transfer its top hat to this contract. This function transfers the top hat back to the Safe after - * creating the role hat. - * - * @dev The function simply calls `_createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. - * - * @dev Stream funds on Roles are targeted at the hat's smart account. In order to withdraw funds from the stream, the - * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer. - * - * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order - * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. - * See: https://github.com/decentdao/decent-interface/issues/2402 - */ - function createRoleHat(CreateRoleHatParams calldata params) external { - _createHatAndAccountAndMintAndStreams( - params.hatsProtocol, - params.registry, - params.topHatAccount, - params.hatsAccountImplementation, - params.adminHatId, - params.hat - ); - - params.hatsProtocol.transferHat( - params.topHatId, - address(this), - msg.sender - ); - } - - /** - * @notice Creates a new termed role hat and any streams on it. - * - * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disable after. - * - * @dev In order for the module to be able to create hats on behalf of the Safe, the Safe must first - * transfer its top hat to this contract. This function transfers the top hat back to the Safe after - * creating the role hat. - * - * @dev The function simply calls `_createTermedHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. - * - * @dev Stream funds on Termed Roles are targeted directly at the nominated wearer. - * The wearer should directly call `withdraw-` on the Sablier contract. - * - * @dev Termed Role hat creation, minting, and stream creation are handled here in order - * to avoid a race condition where not more than one active proposal to create a new termed role can exist at a time. - * See: https://github.com/decentdao/decent-interface/issues/2402 - */ - function createTermedRoleHat( - CreateTermedRoleHatParams calldata params - ) external { - _createTermedHatAndAccountAndMintAndStreams( - params.hatsProtocol, - params.topHatAccount, - params.hatsModuleFactory.createHatsModule( // Create election module and set as eligibility - params.hatsElectionEligibilityImplementation, - params.hatsProtocol.getNextId(params.adminHatId), - abi.encode(params.topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] - abi.encode(params.hat.termedParam.termEndDateTs), - uint256(SALT) - ), - params.adminHatId, - params.hat - ); - - params.hatsProtocol.transferHat( - params.topHatId, - address(this), - msg.sender - ); - } - /* ///////////////////////////////////////////////////////////////////////////// INTERAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ diff --git a/test/DecentHatsCreationModule.test.ts b/test/DecentHatsCreationModule.test.ts index 2f6d5956..be6ebd33 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -671,296 +671,5 @@ describe('DecentHats', () => { expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); }); }); - - describe('Creating a new hat on existing Tree', () => { - let createRoleHatPromise: Promise; - const topHatId = 0; - - beforeEach(async () => { - try { - await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsCreationModuleAddress, - transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, - }, - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, - moduleProxyFactory: await moduleProxyFactory.getAddress(), - decentAutonomousAdminMasterCopy: - await decentAutonomousAdminMasterCopy.getAddress(), - hats: [], - }, - ], - ), - signers: [dao], - }); - } catch (e) { - console.error('Error creating tree', e); - } - const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - - createRoleHatPromise = executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsCreationModuleAddress, - transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( - 'createRoleHat', - [ - { - hatsProtocol: mockHatsAddress, - registry: await erc6551Registry.getAddress(), - topHatAccount: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - hatsAccountImplementation: mockHatsAccountImplementationAddress, - adminHatId: 1, - topHatId, - hat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: true, - wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - }, - ], - ), - signers: [dao], - }); - }); - - it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { - await expect(createRoleHatPromise).to.be.reverted; - }); - - it('Emits an ExecutionSuccess event', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); - }); - - it('Emits an ExecutionFromModuleSuccess event', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - await expect(await createRoleHatPromise) - .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsCreationModuleAddress); - }); - - it('Transfers the top hat back to the Safe', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - - const isModuleWearerOfTopHat = await mockHats.isWearerOfHat( - decentHatsCreationModuleAddress, - topHatId, - ); - expect(isModuleWearerOfTopHat).to.equal(true); - - await createRoleHatPromise; - - const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); - expect(isSafeWearerOfTopHat).to.equal(true); - }); - - it('Actually creates the new hat', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - - const hatsCountBeforeCreate = await mockHats.hatId(); - expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat - - await createRoleHatPromise; - - const newHatId = await mockHats.hatId(); - expect(newHatId).to.equal(3); // + newly created hat - }); - }); - - describe('Creating a new Termed hat on existing tree', () => { - let createRoleHatPromise: Promise; - const topHatId = 0; - - beforeEach(async () => { - try { - await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsCreationModuleAddress, - transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, - }, - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, - moduleProxyFactory: await moduleProxyFactory.getAddress(), - decentAutonomousAdminMasterCopy: - await decentAutonomousAdminMasterCopy.getAddress(), - hats: [], - }, - ], - ), - signers: [dao], - }); - } catch (e) { - console.error('Error creating tree', e); - } - const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - - createRoleHatPromise = executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsCreationModuleAddress, - transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( - 'createTermedRoleHat', - [ - { - hatsProtocol: mockHatsAddress, - registry: await erc6551Registry.getAddress(), - topHatAccount: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - hatsAccountImplementation: mockHatsAccountImplementationAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, - hatsModuleFactory: mockHatsModuleFactoryAddress, - adminHatId: 1, - topHatId, - hat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: true, - wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - termedParam: { - termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', - }, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - }, - ], - ), - signers: [dao], - }); - }); - - it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { - await expect(createRoleHatPromise).to.be.reverted; - }); - - it('Emits an ExecutionSuccess event', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); - }); - - it('Emits an ExecutionFromModuleSuccess event', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - await expect(await createRoleHatPromise) - .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsCreationModuleAddress); - }); - - it('Transfers the top hat back to the Safe', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - - const isModuleWearerOfTopHat = await mockHats.isWearerOfHat( - decentHatsCreationModuleAddress, - topHatId, - ); - expect(isModuleWearerOfTopHat).to.equal(true); - - await createRoleHatPromise; - - const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); - expect(isSafeWearerOfTopHat).to.equal(true); - }); - - it('Actually creates the new hat', async () => { - // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsCreationModuleAddress); - - const hatsCountBeforeCreate = await mockHats.hatId(); - expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat - - await createRoleHatPromise; - - const newHatId = await mockHats.hatId(); - expect(newHatId).to.equal(3); // + newly created hat - }); - }); }); }); From 2e2fa29304ad600b99666d02a95f7c48bd07047e Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 12:32:06 -0400 Subject: [PATCH 160/206] Remove "modifiying tree" (adding hats) external functions from contract, and do some light refactoring --- contracts/DecentHatsCreationModule.sol | 442 ++++++++++++++----------- test/DecentHatsCreationModule.test.ts | 140 +++----- 2 files changed, 289 insertions(+), 293 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index d269a008..dfb19611 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -17,6 +17,22 @@ contract DecentHatsCreationModule { bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; + struct TopHatInfo { + uint256 topHatId; + address topHatAccount; + } + + struct TopHat { + string details; + string imageURI; + } + + struct AdminHat { + string details; + string imageURI; + bool isMutable; + } + struct SablierStreamParams { ISablierV2LockupLinear sablier; address sender; @@ -28,19 +44,14 @@ contract DecentHatsCreationModule { bool transferable; } - struct TermedParam { - uint128 termEndDateTs; - address nominatedWearer; - } - struct Hat { address wearer; string details; string imageURI; - SablierStreamParams[] sablierParams; - TermedParam termedParam; uint32 maxSupply; bool isMutable; + uint128 termEndDateTs; + SablierStreamParams[] sablierStreamsParams; } struct CreateTreeParams { @@ -52,32 +63,9 @@ contract DecentHatsCreationModule { address hatsAccountImplementation; address keyValuePairs; address hatsElectionEligibilityImplementation; - Hat adminHat; + TopHat topHat; + AdminHat adminHat; Hat[] hats; - string topHatDetails; - string topHatImageURI; - } - - struct CreateRoleHatParams { - IHats hatsProtocol; - IERC6551Registry registry; - address topHatAccount; - address hatsAccountImplementation; - uint256 adminHatId; - uint256 topHatId; - Hat hat; - } - - struct CreateTermedRoleHatParams { - IHats hatsProtocol; - IERC6551Registry registry; - IHatsModuleFactory hatsModuleFactory; - address topHatAccount; - address hatsAccountImplementation; - address hatsElectionEligibilityImplementation; - uint256 adminHatId; - uint256 topHatId; - Hat hat; } /* ///////////////////////////////////////////////////////////////////////////// @@ -102,78 +90,88 @@ contract DecentHatsCreationModule { * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. */ function createAndDeclareTree(CreateTreeParams calldata params) external { - (uint256 topHatId, address topHatAccount) = _createTopHatAndAccount( - params.hatsProtocol, - params.topHatDetails, - params.topHatImageURI, - params.registry, - params.hatsAccountImplementation + IHats hatsProtocol = params.hatsProtocol; + address hatsAccountImplementation = params.hatsAccountImplementation; + IERC6551Registry registry = params.registry; + + // Create Top Hat + TopHatInfo memory topHatInfo = processTopHat( + hatsProtocol, + registry, + hatsAccountImplementation, + params.keyValuePairs, + params.topHat ); - _declareSafeHatTree(params.keyValuePairs, topHatId); - - (uint256 adminHatId, ) = _createAdminHatAndAccount( - params.hatsProtocol, - params.registry, + // Create Admin Hat + uint256 adminHatId = processAdminHat( + hatsProtocol, + registry, + hatsAccountImplementation, + topHatInfo, params.moduleProxyFactory, params.decentAutonomousAdminMasterCopy, - params.hatsAccountImplementation, - topHatAccount, - topHatId, params.adminHat ); for (uint256 i = 0; i < params.hats.length; ) { - // {assuption} if 0 nominatedWearers, then it is not a termed role - if (params.hats[i].termedParam.nominatedWearer != address(0)) { - // Create election module and set as eligiblity - _createTermedHatAndAccountAndMintAndStreams( - params.hatsProtocol, - topHatAccount, - params.hatsModuleFactory.createHatsModule( // Create election module and set as eligibility - params.hatsElectionEligibilityImplementation, - params.hatsProtocol.getNextId(adminHatId), - abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] - abi.encode(params.hats[i].termedParam.termEndDateTs), - uint256(SALT) - ), - adminHatId, - params.hats[i] - ); - } else { - _createHatAndAccountAndMintAndStreams( - params.hatsProtocol, - params.registry, - topHatAccount, - params.hatsAccountImplementation, - adminHatId, - params.hats[i] - ); - } + processHat( + hatsProtocol, + registry, + hatsAccountImplementation, + topHatInfo, + params.hatsModuleFactory, + params.hatsElectionEligibilityImplementation, + adminHatId, + params.hats[i] + ); unchecked { ++i; } } - params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); + hatsProtocol.transferHat( + topHatInfo.topHatId, + address(this), + msg.sender + ); } /* ///////////////////////////////////////////////////////////////////////////// - INTERAL FUNCTIONS + INTERNAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ - function _declareSafeHatTree( - address _keyValuePairs, - uint256 topHatId - ) internal { + function processTopHat( + IHats hatsProtocol, + IERC6551Registry registry, + address hatsAccountImplementation, + address keyValuePairs, + TopHat memory topHat + ) internal returns (TopHatInfo memory topHatInfo) { + // Mint top hat + topHatInfo.topHatId = hatsProtocol.mintTopHat( + address(this), + topHat.details, + topHat.imageURI + ); + + // Create top hat account + topHatInfo.topHatAccount = registry.createAccount( + hatsAccountImplementation, + SALT, + block.chainid, + address(hatsProtocol), + topHatInfo.topHatId + ); + + // Declare Top Hat ID to Safe via KeyValuePairs string[] memory keys = new string[](1); string[] memory values = new string[](1); keys[0] = "topHatId"; - values[0] = Strings.toString(topHatId); - + values[0] = Strings.toString(topHatInfo.topHatId); IAvatar(msg.sender).execTransactionFromModule( - _keyValuePairs, + keyValuePairs, 0, abi.encodeWithSignature( "updateValues(string[],string[])", @@ -184,71 +182,82 @@ contract DecentHatsCreationModule { ); } - function _createTopHatAndAccount( - IHats _hatsProtocol, - string memory _topHatDetails, - string memory _topHatImageURI, - IERC6551Registry _registry, - address _hatsAccountImplementation - ) internal returns (uint256 topHatId, address topHatAccount) { - topHatId = _hatsProtocol.mintTopHat( - address(this), - _topHatDetails, - _topHatImageURI - ); - - topHatAccount = _registry.createAccount( - _hatsAccountImplementation, - SALT, - block.chainid, - address(_hatsProtocol), - topHatId - ); - } - - function _createHatAndAccountAndMintAndStreams( + function processAdminHat( IHats hatsProtocol, IERC6551Registry registry, - address topHatAccount, address hatsAccountImplementation, - uint256 adminHatId, - Hat calldata hat - ) internal returns (uint256 hatId, address accountAddress) { - hatId = hatsProtocol.createHat( - adminHatId, - hat.details, - hat.maxSupply, - topHatAccount, - topHatAccount, - hat.isMutable, - hat.imageURI + TopHatInfo memory topHatInfo, + ModuleProxyFactory moduleProxyFactory, + address decentAutonomousAdminMasterCopy, + AdminHat memory adminHat + ) internal returns (uint256 adminHatId) { + // Create Admin Hat + adminHatId = hatsProtocol.createHat( + topHatInfo.topHatId, + adminHat.details, + 1, // only one Admin Hat + topHatInfo.topHatAccount, + topHatInfo.topHatAccount, + adminHat.isMutable, + adminHat.imageURI ); - accountAddress = registry.createAccount( + // Create Admin Hat's ERC6551 Account + registry.createAccount( hatsAccountImplementation, SALT, block.chainid, address(hatsProtocol), - hatId + adminHatId ); - hatsProtocol.mintHat(hatId, hat.wearer); + // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat + address autonomousAdminModule = moduleProxyFactory.deployModule( + decentAutonomousAdminMasterCopy, + abi.encodeWithSignature("setUp(bytes)", bytes("")), + uint256( + keccak256( + abi.encodePacked( + // for the salt, we'll concatenate our static salt with the id of the Admin Hat + SALT, + adminHatId + ) + ) + ) + ); - for (uint256 i = 0; i < hat.sablierParams.length; ) { - _createSablierStream(hat.sablierParams[i], accountAddress); - unchecked { - ++i; - } + // Mint Hat to the Decent Autonomous Admin Module + hatsProtocol.mintHat(adminHatId, autonomousAdminModule); + } + + function createEligibilityModule( + IHats hatsProtocol, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionEligibilityImplementation, + TopHatInfo memory topHatInfo, + uint256 adminHatId, + uint128 termEndDateTs + ) internal returns (address) { + if (termEndDateTs != 0) { + return + hatsModuleFactory.createHatsModule( + hatsElectionEligibilityImplementation, + hatsProtocol.getNextId(adminHatId), + abi.encode(topHatInfo.topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] + abi.encode(termEndDateTs), + uint256(SALT) + ); } + return topHatInfo.topHatAccount; } - function _createTermedHatAndAccountAndMintAndStreams( + function createAndMintHat( IHats hatsProtocol, - address topHatAccount, - address eligibilityAddress, uint256 adminHatId, - Hat calldata hat - ) internal { + Hat memory hat, + address eligibilityAddress, + address topHatAccount + ) internal returns (uint256) { uint256 hatId = hatsProtocol.createHat( adminHatId, hat.details, @@ -259,101 +268,134 @@ contract DecentHatsCreationModule { hat.imageURI ); - address[] memory nominatedWearers = new address[](1); - nominatedWearers[0] = hat.termedParam.nominatedWearer; - IHatsElectionEligibility(eligibilityAddress).elect( - hat.termedParam.termEndDateTs, - nominatedWearers - ); - - hatsProtocol.mintHat(hatId, hat.termedParam.nominatedWearer); - - for (uint256 i = 0; i < hat.sablierParams.length; ) { - _createSablierStream( - hat.sablierParams[i], - hat.termedParam.nominatedWearer + // If the hat is termed, nominate the wearer as the eligible member + if (hat.termEndDateTs != 0) { + address[] memory nominatedWearers = new address[](1); + nominatedWearers[0] = hat.wearer; + IHatsElectionEligibility(eligibilityAddress).elect( + hat.termEndDateTs, + nominatedWearers ); - unchecked { - ++i; - } } + + hatsProtocol.mintHat(hatId, hat.wearer); + return hatId; } - function _createAdminHatAndAccount( - IHats hatsProtocol, + function setupStreamRecipient( IERC6551Registry registry, - ModuleProxyFactory moduleProxyFactory, - address decentAutonomousAdminMasterCopy, address hatsAccountImplementation, - address topHatAccount, - uint256 topHatId, - Hat calldata hat - ) internal returns (uint256 adminHatId, address accountAddress) { - adminHatId = hatsProtocol.createHat( - topHatId, - hat.details, - hat.maxSupply, - topHatAccount, - topHatAccount, - hat.isMutable, - hat.imageURI - ); - - accountAddress = registry.createAccount( - hatsAccountImplementation, - SALT, - block.chainid, - address(hatsProtocol), - adminHatId - ); + address hatsProtocol, + uint128 termEndDateTs, + address wearer, + uint256 hatId + ) internal returns (address) { + // If the hat is termed, the wearer is the stream recipient + if (termEndDateTs != 0) { + return wearer; + } - hatsProtocol.mintHat( - adminHatId, - moduleProxyFactory.deployModule( - decentAutonomousAdminMasterCopy, - abi.encodeWithSignature("setUp(bytes)", bytes("")), - uint256(keccak256(abi.encodePacked(SALT, adminHatId))) - ) - ); + // Otherwise, the Hat's smart account is the stream recipient + return + registry.createAccount( + hatsAccountImplementation, + SALT, + block.chainid, + hatsProtocol, + hatId + ); } - function _createSablierStream( - SablierStreamParams memory sablierParams, - address recipient + function processSablierStream( + SablierStreamParams memory streamParams, + address streamRecipient ) internal { - // Approve tokens for Sablier + // Approve tokens for Sablier via a proxy call through the Safe IAvatar(msg.sender).execTransactionFromModule( - sablierParams.asset, + streamParams.asset, 0, abi.encodeWithSignature( "approve(address,uint256)", - sablierParams.sablier, - sablierParams.totalAmount + streamParams.sablier, + streamParams.totalAmount ), Enum.Operation.Call ); - LockupLinear.CreateWithTimestamps memory params = LockupLinear - .CreateWithTimestamps({ - sender: sablierParams.sender, - recipient: recipient, - totalAmount: sablierParams.totalAmount, - asset: IERC20(sablierParams.asset), - cancelable: sablierParams.cancelable, - transferable: sablierParams.transferable, - timestamps: sablierParams.timestamps, - broker: sablierParams.broker - }); - - // Proxy the Sablier call through IAvatar + // Proxy the Sablier call through the Safe IAvatar(msg.sender).execTransactionFromModule( - address(sablierParams.sablier), + address(streamParams.sablier), 0, abi.encodeWithSignature( "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", - params + LockupLinear.CreateWithTimestamps({ + sender: streamParams.sender, + recipient: streamRecipient, + totalAmount: streamParams.totalAmount, + asset: IERC20(streamParams.asset), + cancelable: streamParams.cancelable, + transferable: streamParams.transferable, + timestamps: streamParams.timestamps, + broker: streamParams.broker + }) ), Enum.Operation.Call ); } + + function createSablierStreams( + SablierStreamParams[] memory streamParams, + address streamRecipient + ) internal { + for (uint256 i = 0; i < streamParams.length; ) { + processSablierStream(streamParams[i], streamRecipient); + + unchecked { + ++i; + } + } + } + + function processHat( + IHats hatsProtocol, + IERC6551Registry registry, + address hatsAccountImplementation, + TopHatInfo memory topHatInfo, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionEligibilityImplementation, + uint256 adminHatId, + Hat memory hat + ) internal { + // Create eligibility module if needed + address eligibilityAddress = createEligibilityModule( + hatsProtocol, + hatsModuleFactory, + hatsElectionEligibilityImplementation, + topHatInfo, + adminHatId, + hat.termEndDateTs + ); + + // Create and Mint the Role Hat + uint256 hatId = createAndMintHat( + hatsProtocol, + adminHatId, + hat, + eligibilityAddress, + topHatInfo.topHatAccount + ); + + // Get the stream recipient (based on termed or not) + address streamRecipient = setupStreamRecipient( + registry, + hatsAccountImplementation, + address(hatsProtocol), + hat.termEndDateTs, + hat.wearer, + hatId + ); + + // Create streams + createSablierStreams(hat.sablierStreamsParams, streamRecipient); + } } diff --git a/test/DecentHatsCreationModule.test.ts b/test/DecentHatsCreationModule.test.ts index be6ebd33..86586281 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -172,54 +172,44 @@ describe('DecentHats', () => { [ { hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + hatsModuleFactory: mockHatsModuleFactoryAddress, moduleProxyFactory: await moduleProxyFactory.getAddress(), + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + hatsAccountImplementation: mockHatsAccountImplementationAddress, + keyValuePairs: await keyValuePairs.getAddress(), + hatsElectionEligibilityImplementation: + mockHatsElectionEligibilityImplementationAddress, + + topHat: { + details: '', + imageURI: '', + }, adminHat: { - maxSupply: 1, details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, }, hats: [ { - maxSupply: 1, + wearer: ethers.ZeroAddress, details: '', imageURI: '', + maxSupply: 1, isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, + termEndDateTs: 0, + sablierStreamsParams: [], }, { - maxSupply: 1, + wearer: ethers.ZeroAddress, details: '', imageURI: '', + maxSupply: 1, isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, + termEndDateTs: 0, + sablierStreamsParams: [], }, ], - hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, }, ], ), @@ -258,23 +248,17 @@ describe('DecentHats', () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', + topHat: { + details: '', + imageURI: '', + }, decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { - maxSupply: 1, details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, }, hats: [], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -335,21 +319,16 @@ describe('DecentHats', () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', + topHat: { + details: '', + imageURI: '', + }, decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { - maxSupply: 1, details: '', imageURI: '', isMutable: true, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, }, hats: [ { @@ -357,24 +336,18 @@ describe('DecentHats', () => { details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearer: '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', - }, + wearer: '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', + sablierStreamsParams: [], + termEndDateTs: BigInt(Date.now() + 100000), }, { maxSupply: 1, details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: BigInt(Date.now() + 100000), - nominatedWearer: '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', - }, + wearer: '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', + sablierStreamsParams: [], + termEndDateTs: BigInt(Date.now() + 100000), }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -422,21 +395,16 @@ describe('DecentHats', () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', + topHat: { + details: '', + imageURI: '', + }, decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { - maxSupply: 1, details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, }, hats: [ { @@ -445,7 +413,7 @@ describe('DecentHats', () => { imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, - sablierParams: [ + sablierStreamsParams: [ { sablier: mockSablierAddress, sender: gnosisSafeAddress, @@ -461,10 +429,7 @@ describe('DecentHats', () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, + termEndDateTs: 0, }, { maxSupply: 1, @@ -472,11 +437,8 @@ describe('DecentHats', () => { imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, + sablierStreamsParams: [], + termEndDateTs: 0, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -555,21 +517,16 @@ describe('DecentHats', () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', + topHat: { + details: '', + imageURI: '', + }, decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { - maxSupply: 1, details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, }, hats: [ { @@ -578,7 +535,7 @@ describe('DecentHats', () => { imageURI: '', isMutable: false, wearer: ethers.ZeroAddress, - sablierParams: [ + sablierStreamsParams: [ { sablier: mockSablierAddress, sender: gnosisSafeAddress, @@ -608,10 +565,7 @@ describe('DecentHats', () => { broker: { account: ethers.ZeroAddress, fee: 0 }, }, ], - termedParam: { - termEndDateTs: 0, - nominatedWearer: ethers.ZeroAddress, - }, + termEndDateTs: 0, }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, From ca2be1f9cc6e09db73894f24403df96dab1d5d99 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 12:34:30 -0400 Subject: [PATCH 161/206] Move functions around, add some comments --- contracts/DecentHatsCreationModule.sol | 91 ++++++++++++++------------ 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index dfb19611..e818c6f3 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -230,6 +230,50 @@ contract DecentHatsCreationModule { hatsProtocol.mintHat(adminHatId, autonomousAdminModule); } + function processHat( + IHats hatsProtocol, + IERC6551Registry registry, + address hatsAccountImplementation, + TopHatInfo memory topHatInfo, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionEligibilityImplementation, + uint256 adminHatId, + Hat memory hat + ) internal { + // Create eligibility module if needed + address eligibilityAddress = createEligibilityModule( + hatsProtocol, + hatsModuleFactory, + hatsElectionEligibilityImplementation, + topHatInfo, + adminHatId, + hat.termEndDateTs + ); + + // Create and Mint the Role Hat + uint256 hatId = createAndMintHat( + hatsProtocol, + adminHatId, + hat, + eligibilityAddress, + topHatInfo.topHatAccount + ); + + // Get the stream recipient (based on termed or not) + address streamRecipient = setupStreamRecipient( + registry, + hatsAccountImplementation, + address(hatsProtocol), + hat.termEndDateTs, + hat.wearer, + hatId + ); + + // Create streams + createSablierStreams(hat.sablierStreamsParams, streamRecipient); + } + + // Exists to avoid stack too deep errors function createEligibilityModule( IHats hatsProtocol, IHatsModuleFactory hatsModuleFactory, @@ -251,6 +295,7 @@ contract DecentHatsCreationModule { return topHatInfo.topHatAccount; } + // Exists to avoid stack too deep errors function createAndMintHat( IHats hatsProtocol, uint256 adminHatId, @@ -282,6 +327,7 @@ contract DecentHatsCreationModule { return hatId; } + // Exists to avoid stack too deep errors function setupStreamRecipient( IERC6551Registry registry, address hatsAccountImplementation, @@ -306,6 +352,7 @@ contract DecentHatsCreationModule { ); } + // Exists to avoid stack too deep errors function processSablierStream( SablierStreamParams memory streamParams, address streamRecipient @@ -343,6 +390,7 @@ contract DecentHatsCreationModule { ); } + // Exists to avoid stack too deep errors function createSablierStreams( SablierStreamParams[] memory streamParams, address streamRecipient @@ -355,47 +403,4 @@ contract DecentHatsCreationModule { } } } - - function processHat( - IHats hatsProtocol, - IERC6551Registry registry, - address hatsAccountImplementation, - TopHatInfo memory topHatInfo, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionEligibilityImplementation, - uint256 adminHatId, - Hat memory hat - ) internal { - // Create eligibility module if needed - address eligibilityAddress = createEligibilityModule( - hatsProtocol, - hatsModuleFactory, - hatsElectionEligibilityImplementation, - topHatInfo, - adminHatId, - hat.termEndDateTs - ); - - // Create and Mint the Role Hat - uint256 hatId = createAndMintHat( - hatsProtocol, - adminHatId, - hat, - eligibilityAddress, - topHatInfo.topHatAccount - ); - - // Get the stream recipient (based on termed or not) - address streamRecipient = setupStreamRecipient( - registry, - hatsAccountImplementation, - address(hatsProtocol), - hat.termEndDateTs, - hat.wearer, - hatId - ); - - // Create streams - createSablierStreams(hat.sablierStreamsParams, streamRecipient); - } } From 971ba590802220ae5774c7dfcfadce46a7b5d3fe Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 12:38:40 -0400 Subject: [PATCH 162/206] Remove unneeded struct via refactoring --- contracts/DecentHatsCreationModule.sol | 76 +++++++++++++------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index e818c6f3..3e036838 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -17,17 +17,12 @@ contract DecentHatsCreationModule { bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; - struct TopHatInfo { - uint256 topHatId; - address topHatAccount; - } - - struct TopHat { + struct TopHatParams { string details; string imageURI; } - struct AdminHat { + struct AdminHatParams { string details; string imageURI; bool isMutable; @@ -44,7 +39,7 @@ contract DecentHatsCreationModule { bool transferable; } - struct Hat { + struct HatParams { address wearer; string details; string imageURI; @@ -63,9 +58,9 @@ contract DecentHatsCreationModule { address hatsAccountImplementation; address keyValuePairs; address hatsElectionEligibilityImplementation; - TopHat topHat; - AdminHat adminHat; - Hat[] hats; + TopHatParams topHat; + AdminHatParams adminHat; + HatParams[] hats; } /* ///////////////////////////////////////////////////////////////////////////// @@ -95,7 +90,7 @@ contract DecentHatsCreationModule { IERC6551Registry registry = params.registry; // Create Top Hat - TopHatInfo memory topHatInfo = processTopHat( + (uint256 topHatId, address topHatAccount) = processTopHat( hatsProtocol, registry, hatsAccountImplementation, @@ -108,22 +103,25 @@ contract DecentHatsCreationModule { hatsProtocol, registry, hatsAccountImplementation, - topHatInfo, + topHatId, + topHatAccount, params.moduleProxyFactory, params.decentAutonomousAdminMasterCopy, params.adminHat ); for (uint256 i = 0; i < params.hats.length; ) { + HatParams memory hat = params.hats[i]; processHat( hatsProtocol, registry, hatsAccountImplementation, - topHatInfo, + topHatId, + topHatAccount, params.hatsModuleFactory, params.hatsElectionEligibilityImplementation, adminHatId, - params.hats[i] + hat ); unchecked { @@ -131,11 +129,7 @@ contract DecentHatsCreationModule { } } - hatsProtocol.transferHat( - topHatInfo.topHatId, - address(this), - msg.sender - ); + hatsProtocol.transferHat(topHatId, address(this), msg.sender); } /* ///////////////////////////////////////////////////////////////////////////// @@ -147,29 +141,29 @@ contract DecentHatsCreationModule { IERC6551Registry registry, address hatsAccountImplementation, address keyValuePairs, - TopHat memory topHat - ) internal returns (TopHatInfo memory topHatInfo) { + TopHatParams memory topHat + ) internal returns (uint256 topHatId, address topHatAccount) { // Mint top hat - topHatInfo.topHatId = hatsProtocol.mintTopHat( + topHatId = hatsProtocol.mintTopHat( address(this), topHat.details, topHat.imageURI ); // Create top hat account - topHatInfo.topHatAccount = registry.createAccount( + topHatAccount = registry.createAccount( hatsAccountImplementation, SALT, block.chainid, address(hatsProtocol), - topHatInfo.topHatId + topHatId ); // Declare Top Hat ID to Safe via KeyValuePairs string[] memory keys = new string[](1); string[] memory values = new string[](1); keys[0] = "topHatId"; - values[0] = Strings.toString(topHatInfo.topHatId); + values[0] = Strings.toString(topHatId); IAvatar(msg.sender).execTransactionFromModule( keyValuePairs, 0, @@ -186,18 +180,19 @@ contract DecentHatsCreationModule { IHats hatsProtocol, IERC6551Registry registry, address hatsAccountImplementation, - TopHatInfo memory topHatInfo, + uint256 topHatId, + address topHatAccount, ModuleProxyFactory moduleProxyFactory, address decentAutonomousAdminMasterCopy, - AdminHat memory adminHat + AdminHatParams memory adminHat ) internal returns (uint256 adminHatId) { // Create Admin Hat adminHatId = hatsProtocol.createHat( - topHatInfo.topHatId, + topHatId, adminHat.details, 1, // only one Admin Hat - topHatInfo.topHatAccount, - topHatInfo.topHatAccount, + topHatAccount, + topHatAccount, adminHat.isMutable, adminHat.imageURI ); @@ -234,18 +229,20 @@ contract DecentHatsCreationModule { IHats hatsProtocol, IERC6551Registry registry, address hatsAccountImplementation, - TopHatInfo memory topHatInfo, + uint256 topHatId, + address topHatAccount, IHatsModuleFactory hatsModuleFactory, address hatsElectionEligibilityImplementation, uint256 adminHatId, - Hat memory hat + HatParams memory hat ) internal { // Create eligibility module if needed address eligibilityAddress = createEligibilityModule( hatsProtocol, hatsModuleFactory, hatsElectionEligibilityImplementation, - topHatInfo, + topHatId, + topHatAccount, adminHatId, hat.termEndDateTs ); @@ -256,7 +253,7 @@ contract DecentHatsCreationModule { adminHatId, hat, eligibilityAddress, - topHatInfo.topHatAccount + topHatAccount ); // Get the stream recipient (based on termed or not) @@ -278,7 +275,8 @@ contract DecentHatsCreationModule { IHats hatsProtocol, IHatsModuleFactory hatsModuleFactory, address hatsElectionEligibilityImplementation, - TopHatInfo memory topHatInfo, + uint256 topHatId, + address topHatAccount, uint256 adminHatId, uint128 termEndDateTs ) internal returns (address) { @@ -287,19 +285,19 @@ contract DecentHatsCreationModule { hatsModuleFactory.createHatsModule( hatsElectionEligibilityImplementation, hatsProtocol.getNextId(adminHatId), - abi.encode(topHatInfo.topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] + abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] abi.encode(termEndDateTs), uint256(SALT) ); } - return topHatInfo.topHatAccount; + return topHatAccount; } // Exists to avoid stack too deep errors function createAndMintHat( IHats hatsProtocol, uint256 adminHatId, - Hat memory hat, + HatParams memory hat, address eligibilityAddress, address topHatAccount ) internal returns (uint256) { From 302c147d80fb50e3cc14c39da20d28ee1a901eef Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 12:49:26 -0400 Subject: [PATCH 163/206] Rename "election eligibility" to "elections eligibility", and "registry" to "erc6551Registry" --- contracts/DecentAutonomousAdmin.sol | 8 ++-- contracts/DecentHatsCreationModule.sol | 22 ++++----- .../IHatsElectionsEligibility.sol} | 2 +- .../mocks/MockHatsElectionEligibility.sol | 4 +- contracts/mocks/MockHatsModuleFactory.sol | 4 +- test/DecentAutonomousAdmin.test.ts | 8 ++-- test/DecentHatsCreationModule.test.ts | 45 +++++++++---------- 7 files changed, 46 insertions(+), 47 deletions(-) rename contracts/interfaces/hats/full/{IHatsElectionEligibility.sol => modules/IHatsElectionsEligibility.sol} (98%) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index 36bdf039..feb879b9 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.28; import {IHats} from "./interfaces/hats/full/IHats.sol"; -import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; +import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; import {FactoryFriendly} from "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol"; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {IDecentAutonomousAdmin} from "./interfaces/IDecentAutonomousAdmin.sol"; @@ -26,9 +26,9 @@ contract DecentAutonomousAdmin is false ) revert NotCurrentWearer(); - IHatsElectionEligibility hatsElectionModule = IHatsElectionEligibility( - args.hatsProtocol.getHatEligibilityModule(args.hatId) - ); + IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility( + args.hatsProtocol.getHatEligibilityModule(args.hatId) + ); hatsElectionModule.startNextTerm(); diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index 3e036838..34bf0600 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -9,7 +9,7 @@ import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/full/IHats.sol"; import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; -import {IHatsElectionEligibility} from "./interfaces/hats/full/IHatsElectionEligibility.sol"; +import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; @@ -51,13 +51,13 @@ contract DecentHatsCreationModule { struct CreateTreeParams { IHats hatsProtocol; - IERC6551Registry registry; + IERC6551Registry erc6551Registry; IHatsModuleFactory hatsModuleFactory; ModuleProxyFactory moduleProxyFactory; + address keyValuePairs; address decentAutonomousAdminMasterCopy; address hatsAccountImplementation; - address keyValuePairs; - address hatsElectionEligibilityImplementation; + address hatsElectionsEligibilityImplementation; TopHatParams topHat; AdminHatParams adminHat; HatParams[] hats; @@ -87,7 +87,7 @@ contract DecentHatsCreationModule { function createAndDeclareTree(CreateTreeParams calldata params) external { IHats hatsProtocol = params.hatsProtocol; address hatsAccountImplementation = params.hatsAccountImplementation; - IERC6551Registry registry = params.registry; + IERC6551Registry registry = params.erc6551Registry; // Create Top Hat (uint256 topHatId, address topHatAccount) = processTopHat( @@ -119,7 +119,7 @@ contract DecentHatsCreationModule { topHatId, topHatAccount, params.hatsModuleFactory, - params.hatsElectionEligibilityImplementation, + params.hatsElectionsEligibilityImplementation, adminHatId, hat ); @@ -232,7 +232,7 @@ contract DecentHatsCreationModule { uint256 topHatId, address topHatAccount, IHatsModuleFactory hatsModuleFactory, - address hatsElectionEligibilityImplementation, + address hatsElectionsEligibilityImplementation, uint256 adminHatId, HatParams memory hat ) internal { @@ -240,7 +240,7 @@ contract DecentHatsCreationModule { address eligibilityAddress = createEligibilityModule( hatsProtocol, hatsModuleFactory, - hatsElectionEligibilityImplementation, + hatsElectionsEligibilityImplementation, topHatId, topHatAccount, adminHatId, @@ -274,7 +274,7 @@ contract DecentHatsCreationModule { function createEligibilityModule( IHats hatsProtocol, IHatsModuleFactory hatsModuleFactory, - address hatsElectionEligibilityImplementation, + address hatsElectionsEligibilityImplementation, uint256 topHatId, address topHatAccount, uint256 adminHatId, @@ -283,7 +283,7 @@ contract DecentHatsCreationModule { if (termEndDateTs != 0) { return hatsModuleFactory.createHatsModule( - hatsElectionEligibilityImplementation, + hatsElectionsEligibilityImplementation, hatsProtocol.getNextId(adminHatId), abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] abi.encode(termEndDateTs), @@ -315,7 +315,7 @@ contract DecentHatsCreationModule { if (hat.termEndDateTs != 0) { address[] memory nominatedWearers = new address[](1); nominatedWearers[0] = hat.wearer; - IHatsElectionEligibility(eligibilityAddress).elect( + IHatsElectionsEligibility(eligibilityAddress).elect( hat.termEndDateTs, nominatedWearers ); diff --git a/contracts/interfaces/hats/full/IHatsElectionEligibility.sol b/contracts/interfaces/hats/full/modules/IHatsElectionsEligibility.sol similarity index 98% rename from contracts/interfaces/hats/full/IHatsElectionEligibility.sol rename to contracts/interfaces/hats/full/modules/IHatsElectionsEligibility.sol index 3b0c7c67..8d2fb835 100644 --- a/contracts/interfaces/hats/full/IHatsElectionEligibility.sol +++ b/contracts/interfaces/hats/full/modules/IHatsElectionsEligibility.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.13; -interface IHatsElectionEligibility { +interface IHatsElectionsEligibility { event ElectionOpened(uint128 nextTermEnd); event ElectionCompleted(uint128 termEnd, address[] winners); event NewTermStarted(uint128 termEnd); diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionEligibility.sol index 5c9c4212..6dec84c8 100644 --- a/contracts/mocks/MockHatsElectionEligibility.sol +++ b/contracts/mocks/MockHatsElectionEligibility.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IHatsElectionEligibility} from "../interfaces/hats/full/IHatsElectionEligibility.sol"; +import {IHatsElectionsEligibility} from "../interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; -contract MockHatsElectionEligibility is IHatsElectionEligibility { +contract MockHatsElectionsEligibility is IHatsElectionsEligibility { function currentTermEnd() external view returns (uint128) {} function nextTermEnd() external view returns (uint128) {} diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol index df5479d3..57ae687b 100644 --- a/contracts/mocks/MockHatsModuleFactory.sol +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import {IHatsModuleFactory} from "../interfaces/hats/full/IHatsModuleFactory.sol"; -import {MockHatsElectionEligibility} from "./MockHatsElectionEligibility.sol"; +import {MockHatsElectionsEligibility} from "./MockHatsElectionEligibility.sol"; contract MockHatsModuleFactory is IHatsModuleFactory { function createHatsModule( @@ -13,7 +13,7 @@ contract MockHatsModuleFactory is IHatsModuleFactory { uint256 ) external override returns (address _instance) { // Deploy a new instance of MockHatsElectionEligibility - MockHatsElectionEligibility newModule = new MockHatsElectionEligibility(); + MockHatsElectionsEligibility newModule = new MockHatsElectionsEligibility(); _instance = address(newModule); } diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index a20b00a0..5f009833 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -6,8 +6,8 @@ import { DecentAutonomousAdmin__factory, MockHats, MockHats__factory, - MockHatsElectionEligibility, - MockHatsElectionEligibility__factory, + MockHatsElectionsEligibility, + MockHatsElectionsEligibility__factory, } from '../typechain-types'; describe('DecentAutonomousAdminHat', function () { @@ -19,7 +19,7 @@ describe('DecentAutonomousAdminHat', function () { // Contract instances let hatsProtocol: MockHats; - let hatsElectionModule: MockHatsElectionEligibility; + let hatsElectionModule: MockHatsElectionsEligibility; let decentAutonomousAdminInstance: DecentAutonomousAdmin; // Variables @@ -33,7 +33,7 @@ describe('DecentAutonomousAdminHat', function () { hatsProtocol = await new MockHats__factory(deployer).deploy(); // Deploy MockHatsElectionEligibility (Eligibility Module) - hatsElectionModule = await new MockHatsElectionEligibility__factory(deployer).deploy(); + hatsElectionModule = await new MockHatsElectionsEligibility__factory(deployer).deploy(); // Create Admin Hat const createAdminTx = await hatsProtocol.createHat( diff --git a/test/DecentHatsCreationModule.test.ts b/test/DecentHatsCreationModule.test.ts index 86586281..982ca014 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -23,7 +23,7 @@ import { MockERC20, DecentAutonomousAdmin, DecentAutonomousAdmin__factory, - MockHatsElectionEligibility__factory, + MockHatsElectionsEligibility__factory, MockHatsModuleFactory__factory, ModuleProxyFactory, ModuleProxyFactory__factory, @@ -32,7 +32,7 @@ import { import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; -describe('DecentHats', () => { +describe('DecentHatsCreationModule', () => { let dao: SignerWithAddress; let mockHats: MockHats; @@ -56,7 +56,7 @@ describe('DecentHats', () => { let mockERC20: MockERC20; let mockERC20Address: string; - let mockHatsElectionEligibilityImplementationAddress: string; + let mockHatsElectionsEligibilityImplementationAddress: string; let mockHatsModuleFactoryAddress: string; let moduleProxyFactory: ModuleProxyFactory; @@ -70,10 +70,10 @@ describe('DecentHats', () => { mockHats = await new MockHats__factory(deployer).deploy(); mockHatsAddress = await mockHats.getAddress(); - const mockHatsElectionEligibilityImplementation = - await new MockHatsElectionEligibility__factory(deployer).deploy(); - mockHatsElectionEligibilityImplementationAddress = - await mockHatsElectionEligibilityImplementation.getAddress(); + const mockHatsElectionsEligibilityImplementation = + await new MockHatsElectionsEligibility__factory(deployer).deploy(); + mockHatsElectionsEligibilityImplementationAddress = + await mockHatsElectionsEligibilityImplementation.getAddress(); const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); @@ -172,15 +172,14 @@ describe('DecentHats', () => { [ { hatsProtocol: mockHatsAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), hatsModuleFactory: mockHatsModuleFactoryAddress, moduleProxyFactory: await moduleProxyFactory.getAddress(), decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), hatsAccountImplementation: mockHatsAccountImplementationAddress, keyValuePairs: await keyValuePairs.getAddress(), - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, - + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, topHat: { details: '', imageURI: '', @@ -246,7 +245,7 @@ describe('DecentHats', () => { { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), topHat: { details: '', @@ -262,8 +261,8 @@ describe('DecentHats', () => { }, hats: [], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, }, ], ), @@ -317,7 +316,7 @@ describe('DecentHats', () => { { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), topHat: { details: '', @@ -351,8 +350,8 @@ describe('DecentHats', () => { }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, }, ], ), @@ -393,7 +392,7 @@ describe('DecentHats', () => { { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), topHat: { details: '', @@ -442,8 +441,8 @@ describe('DecentHats', () => { }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, }, ], ), @@ -515,7 +514,7 @@ describe('DecentHats', () => { { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), topHat: { details: '', @@ -569,8 +568,8 @@ describe('DecentHats', () => { }, ], hatsModuleFactory: mockHatsModuleFactoryAddress, - hatsElectionEligibilityImplementation: - mockHatsElectionEligibilityImplementationAddress, + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, }, ], ), From 8f6478af2ef2885a5589689254258ea8f154bbbe Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 13:02:10 -0400 Subject: [PATCH 164/206] Fix deployment script --- deploy/core/019_deploy_DecentHats.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/core/019_deploy_DecentHats.ts b/deploy/core/019_deploy_DecentHats.ts index 6f48e56d..41e110aa 100644 --- a/deploy/core/019_deploy_DecentHats.ts +++ b/deploy/core/019_deploy_DecentHats.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, 'DecentHats'); + await deployNonUpgradeable(hre, 'DecentHatsCreationModule'); }; export default func; From 7b5a8b3b81739c4c99bfab45a5290b8cbb08ba42 Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 30 Oct 2024 18:09:04 +0000 Subject: [PATCH 165/206] Add DecentHatsUtil, have DecentHatsCreationModule use its shared code --- contracts/DecentHatsCreationModule.sol | 126 +++---------------------- contracts/DecentHatsUtils.sol | 107 +++++++++++++++++++++ 2 files changed, 121 insertions(+), 112 deletions(-) create mode 100644 contracts/DecentHatsUtils.sol diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index 34bf0600..178b5de1 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -12,11 +12,9 @@ import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol" import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; +import {DecentHatsUtils} from "./DecentHatsUtils.sol"; -contract DecentHatsCreationModule { - bytes32 public constant SALT = - 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; - +contract DecentHatsCreationModule is DecentHatsUtils { struct TopHatParams { string details; string imageURI; @@ -28,27 +26,6 @@ contract DecentHatsCreationModule { bool isMutable; } - struct SablierStreamParams { - ISablierV2LockupLinear sablier; - address sender; - address asset; - LockupLinear.Timestamps timestamps; - Broker broker; - uint128 totalAmount; - bool cancelable; - bool transferable; - } - - struct HatParams { - address wearer; - string details; - string imageURI; - uint32 maxSupply; - bool isMutable; - uint128 termEndDateTs; - SablierStreamParams[] sablierStreamsParams; - } - struct CreateTreeParams { IHats hatsProtocol; IERC6551Registry erc6551Registry; @@ -90,7 +67,7 @@ contract DecentHatsCreationModule { IERC6551Registry registry = params.erc6551Registry; // Create Top Hat - (uint256 topHatId, address topHatAccount) = processTopHat( + (uint256 topHatId, address topHatAccount) = _processTopHat( hatsProtocol, registry, hatsAccountImplementation, @@ -99,7 +76,7 @@ contract DecentHatsCreationModule { ); // Create Admin Hat - uint256 adminHatId = processAdminHat( + uint256 adminHatId = _processAdminHat( hatsProtocol, registry, hatsAccountImplementation, @@ -112,7 +89,7 @@ contract DecentHatsCreationModule { for (uint256 i = 0; i < params.hats.length; ) { HatParams memory hat = params.hats[i]; - processHat( + _processHat( hatsProtocol, registry, hatsAccountImplementation, @@ -136,7 +113,7 @@ contract DecentHatsCreationModule { INTERNAL FUNCTIONS ///////////////////////////////////////////////////////////////////////////// */ - function processTopHat( + function _processTopHat( IHats hatsProtocol, IERC6551Registry registry, address hatsAccountImplementation, @@ -176,7 +153,7 @@ contract DecentHatsCreationModule { ); } - function processAdminHat( + function _processAdminHat( IHats hatsProtocol, IERC6551Registry registry, address hatsAccountImplementation, @@ -225,7 +202,7 @@ contract DecentHatsCreationModule { hatsProtocol.mintHat(adminHatId, autonomousAdminModule); } - function processHat( + function _processHat( IHats hatsProtocol, IERC6551Registry registry, address hatsAccountImplementation, @@ -237,7 +214,7 @@ contract DecentHatsCreationModule { HatParams memory hat ) internal { // Create eligibility module if needed - address eligibilityAddress = createEligibilityModule( + address eligibilityAddress = _createEligibilityModule( hatsProtocol, hatsModuleFactory, hatsElectionsEligibilityImplementation, @@ -248,7 +225,7 @@ contract DecentHatsCreationModule { ); // Create and Mint the Role Hat - uint256 hatId = createAndMintHat( + uint256 hatId = _createAndMintHat( hatsProtocol, adminHatId, hat, @@ -257,7 +234,7 @@ contract DecentHatsCreationModule { ); // Get the stream recipient (based on termed or not) - address streamRecipient = setupStreamRecipient( + address streamRecipient = _setupStreamRecipient( registry, hatsAccountImplementation, address(hatsProtocol), @@ -267,34 +244,11 @@ contract DecentHatsCreationModule { ); // Create streams - createSablierStreams(hat.sablierStreamsParams, streamRecipient); + _processSablierStreams(hat.sablierStreamsParams, streamRecipient); } // Exists to avoid stack too deep errors - function createEligibilityModule( - IHats hatsProtocol, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionsEligibilityImplementation, - uint256 topHatId, - address topHatAccount, - uint256 adminHatId, - uint128 termEndDateTs - ) internal returns (address) { - if (termEndDateTs != 0) { - return - hatsModuleFactory.createHatsModule( - hatsElectionsEligibilityImplementation, - hatsProtocol.getNextId(adminHatId), - abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] - abi.encode(termEndDateTs), - uint256(SALT) - ); - } - return topHatAccount; - } - - // Exists to avoid stack too deep errors - function createAndMintHat( + function _createAndMintHat( IHats hatsProtocol, uint256 adminHatId, HatParams memory hat, @@ -326,7 +280,7 @@ contract DecentHatsCreationModule { } // Exists to avoid stack too deep errors - function setupStreamRecipient( + function _setupStreamRecipient( IERC6551Registry registry, address hatsAccountImplementation, address hatsProtocol, @@ -349,56 +303,4 @@ contract DecentHatsCreationModule { hatId ); } - - // Exists to avoid stack too deep errors - function processSablierStream( - SablierStreamParams memory streamParams, - address streamRecipient - ) internal { - // Approve tokens for Sablier via a proxy call through the Safe - IAvatar(msg.sender).execTransactionFromModule( - streamParams.asset, - 0, - abi.encodeWithSignature( - "approve(address,uint256)", - streamParams.sablier, - streamParams.totalAmount - ), - Enum.Operation.Call - ); - - // Proxy the Sablier call through the Safe - IAvatar(msg.sender).execTransactionFromModule( - address(streamParams.sablier), - 0, - abi.encodeWithSignature( - "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", - LockupLinear.CreateWithTimestamps({ - sender: streamParams.sender, - recipient: streamRecipient, - totalAmount: streamParams.totalAmount, - asset: IERC20(streamParams.asset), - cancelable: streamParams.cancelable, - transferable: streamParams.transferable, - timestamps: streamParams.timestamps, - broker: streamParams.broker - }) - ), - Enum.Operation.Call - ); - } - - // Exists to avoid stack too deep errors - function createSablierStreams( - SablierStreamParams[] memory streamParams, - address streamRecipient - ) internal { - for (uint256 i = 0; i < streamParams.length; ) { - processSablierStream(streamParams[i], streamRecipient); - - unchecked { - ++i; - } - } - } } diff --git a/contracts/DecentHatsUtils.sol b/contracts/DecentHatsUtils.sol new file mode 100644 index 00000000..0b2eab78 --- /dev/null +++ b/contracts/DecentHatsUtils.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; +import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; +import {IHats} from "./interfaces/hats/full/IHats.sol"; +import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; +import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; +import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; +import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; +import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; + +contract DecentHatsUtils { + bytes32 public constant SALT = + 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; + + struct SablierStreamParams { + ISablierV2LockupLinear sablier; + address sender; + address asset; + LockupLinear.Timestamps timestamps; + Broker broker; + uint128 totalAmount; + bool cancelable; + bool transferable; + } + + struct HatParams { + address wearer; + string details; + string imageURI; + SablierStreamParams[] sablierStreamsParams; + uint128 termEndDateTs; // If 0, this is an untermed Hat + uint32 maxSupply; + bool isMutable; + } + + function _createEligibilityModule( + IHats hatsProtocol, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionsEligibilityImplementation, + uint256 topHatId, + address topHatAccount, + uint256 adminHatId, + uint128 termEndDateTs + ) internal returns (address) { + if (termEndDateTs != 0) { + return + hatsModuleFactory.createHatsModule( + hatsElectionsEligibilityImplementation, + hatsProtocol.getNextId(adminHatId), + abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] + abi.encode(termEndDateTs), + uint256(SALT) + ); + } + return topHatAccount; + } + + function _processSablierStreams( + SablierStreamParams[] memory streamParams, + address streamRecipient + ) internal { + for (uint256 i = 0; i < streamParams.length; ) { + SablierStreamParams memory sablierStreamParams = streamParams[i]; + + // Approve tokens for Sablier + IAvatar(msg.sender).execTransactionFromModule( + sablierStreamParams.asset, + 0, + abi.encodeWithSignature( + "approve(address,uint256)", + sablierStreamParams.sablier, + sablierStreamParams.totalAmount + ), + Enum.Operation.Call + ); + + // Proxy the Sablier call through IAvatar + IAvatar(msg.sender).execTransactionFromModule( + address(sablierStreamParams.sablier), + 0, + abi.encodeWithSignature( + "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", + LockupLinear.CreateWithTimestamps({ + sender: sablierStreamParams.sender, + recipient: streamRecipient, + totalAmount: sablierStreamParams.totalAmount, + asset: IERC20(sablierStreamParams.asset), + cancelable: sablierStreamParams.cancelable, + transferable: sablierStreamParams.transferable, + timestamps: sablierStreamParams.timestamps, + broker: sablierStreamParams.broker + }) + ), + Enum.Operation.Call + ); + + unchecked { + ++i; + } + } + } +} From 1b777b832f88939f2ed252911a90410366e55ddd Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 30 Oct 2024 20:18:27 +0000 Subject: [PATCH 166/206] Proxy all hatProtocol interactions through the context safe; Extracted all resuable code into DecentHatsUtils. Update tests --- contracts/DecentHatsCreationModule.sol | 157 +++++++------------------ contracts/DecentHatsUtils.sol | 128 +++++++++++++++++++- contracts/mocks/MockHats.sol | 8 +- test/DecentHatsCreationModule.test.ts | 12 +- test/DecentHats_0_1_0.test.ts | 31 +++-- test/helpers.ts | 6 +- 6 files changed, 201 insertions(+), 141 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index 178b5de1..7c68dfda 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -105,8 +105,6 @@ contract DecentHatsCreationModule is DecentHatsUtils { ++i; } } - - hatsProtocol.transferHat(topHatId, address(this), msg.sender); } /* ///////////////////////////////////////////////////////////////////////////// @@ -120,11 +118,24 @@ contract DecentHatsCreationModule is DecentHatsUtils { address keyValuePairs, TopHatParams memory topHat ) internal returns (uint256 topHatId, address topHatAccount) { - // Mint top hat - topHatId = hatsProtocol.mintTopHat( - address(this), - topHat.details, - topHat.imageURI + (, bytes memory lastTopHatId) = address(hatsProtocol).call( + abi.encodeWithSignature("lastTopHatId()") + ); + + // topHatId = abi.decode(lastTopHatId, (uint256)) << 224; + topHatId = uint256(bytes32(lastTopHatId)) + 1; + + IAvatar(msg.sender).execTransactionFromModule( + // Mint top hat to the safe + address(hatsProtocol), + 0, + abi.encodeWithSignature( + "mintTopHat(address,string,string)", + msg.sender, + topHat.details, + topHat.imageURI + ), + Enum.Operation.Call ); // Create top hat account @@ -164,14 +175,21 @@ contract DecentHatsCreationModule is DecentHatsUtils { AdminHatParams memory adminHat ) internal returns (uint256 adminHatId) { // Create Admin Hat - adminHatId = hatsProtocol.createHat( - topHatId, - adminHat.details, - 1, // only one Admin Hat - topHatAccount, - topHatAccount, - adminHat.isMutable, - adminHat.imageURI + adminHatId = hatsProtocol.getNextId(topHatId); + IAvatar(msg.sender).execTransactionFromModule( + address(hatsProtocol), + 0, + abi.encodeWithSignature( + "createHat(uint256,string,uint32,address,address,bool,string)", + topHatId, + adminHat.details, + 1, // only one Admin Hat + topHatAccount, + topHatAccount, + adminHat.isMutable, + adminHat.imageURI + ), + Enum.Operation.Call ); // Create Admin Hat's ERC6551 Account @@ -199,108 +217,15 @@ contract DecentHatsCreationModule is DecentHatsUtils { ); // Mint Hat to the Decent Autonomous Admin Module - hatsProtocol.mintHat(adminHatId, autonomousAdminModule); - } - - function _processHat( - IHats hatsProtocol, - IERC6551Registry registry, - address hatsAccountImplementation, - uint256 topHatId, - address topHatAccount, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionsEligibilityImplementation, - uint256 adminHatId, - HatParams memory hat - ) internal { - // Create eligibility module if needed - address eligibilityAddress = _createEligibilityModule( - hatsProtocol, - hatsModuleFactory, - hatsElectionsEligibilityImplementation, - topHatId, - topHatAccount, - adminHatId, - hat.termEndDateTs - ); - - // Create and Mint the Role Hat - uint256 hatId = _createAndMintHat( - hatsProtocol, - adminHatId, - hat, - eligibilityAddress, - topHatAccount - ); - - // Get the stream recipient (based on termed or not) - address streamRecipient = _setupStreamRecipient( - registry, - hatsAccountImplementation, + IAvatar(msg.sender).execTransactionFromModule( address(hatsProtocol), - hat.termEndDateTs, - hat.wearer, - hatId - ); - - // Create streams - _processSablierStreams(hat.sablierStreamsParams, streamRecipient); - } - - // Exists to avoid stack too deep errors - function _createAndMintHat( - IHats hatsProtocol, - uint256 adminHatId, - HatParams memory hat, - address eligibilityAddress, - address topHatAccount - ) internal returns (uint256) { - uint256 hatId = hatsProtocol.createHat( - adminHatId, - hat.details, - hat.maxSupply, - eligibilityAddress, - topHatAccount, - hat.isMutable, - hat.imageURI + 0, + abi.encodeWithSignature( + "mintHat(uint256,address)", + adminHatId, + autonomousAdminModule + ), + Enum.Operation.Call ); - - // If the hat is termed, nominate the wearer as the eligible member - if (hat.termEndDateTs != 0) { - address[] memory nominatedWearers = new address[](1); - nominatedWearers[0] = hat.wearer; - IHatsElectionsEligibility(eligibilityAddress).elect( - hat.termEndDateTs, - nominatedWearers - ); - } - - hatsProtocol.mintHat(hatId, hat.wearer); - return hatId; - } - - // Exists to avoid stack too deep errors - function _setupStreamRecipient( - IERC6551Registry registry, - address hatsAccountImplementation, - address hatsProtocol, - uint128 termEndDateTs, - address wearer, - uint256 hatId - ) internal returns (address) { - // If the hat is termed, the wearer is the stream recipient - if (termEndDateTs != 0) { - return wearer; - } - - // Otherwise, the Hat's smart account is the stream recipient - return - registry.createAccount( - hatsAccountImplementation, - SALT, - block.chainid, - hatsProtocol, - hatId - ); } } diff --git a/contracts/DecentHatsUtils.sol b/contracts/DecentHatsUtils.sol index 0b2eab78..d1cd89fe 100644 --- a/contracts/DecentHatsUtils.sol +++ b/contracts/DecentHatsUtils.sol @@ -38,6 +38,51 @@ contract DecentHatsUtils { bool isMutable; } + function _processHat( + IHats hatsProtocol, + IERC6551Registry registry, + address hatsAccountImplementation, + uint256 topHatId, + address topHatAccount, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionsEligibilityImplementation, + uint256 adminHatId, + HatParams memory hat + ) internal { + // Create eligibility module if needed + address eligibilityAddress = _createEligibilityModule( + hatsProtocol, + hatsModuleFactory, + hatsElectionsEligibilityImplementation, + topHatId, + topHatAccount, + adminHatId, + hat.termEndDateTs + ); + + // Create and Mint the Role Hat + uint256 hatId = _createAndMintHat( + hatsProtocol, + adminHatId, + hat, + eligibilityAddress, + topHatAccount + ); + + // Get the stream recipient (based on termed or not) + address streamRecipient = _setupStreamRecipient( + registry, + hatsAccountImplementation, + address(hatsProtocol), + hat.termEndDateTs, + hat.wearer, + hatId + ); + + // Create streams + _processSablierStreams(hat.sablierStreamsParams, streamRecipient); + } + function _createEligibilityModule( IHats hatsProtocol, IHatsModuleFactory hatsModuleFactory, @@ -46,7 +91,7 @@ contract DecentHatsUtils { address topHatAccount, uint256 adminHatId, uint128 termEndDateTs - ) internal returns (address) { + ) private returns (address) { if (termEndDateTs != 0) { return hatsModuleFactory.createHatsModule( @@ -60,10 +105,89 @@ contract DecentHatsUtils { return topHatAccount; } + function _createAndMintHat( + IHats hatsProtocol, + uint256 adminHatId, + HatParams memory hat, + address eligibilityAddress, + address topHatAccount + ) private returns (uint256) { + uint256 hatId = hatsProtocol.getNextId(adminHatId); + IAvatar(msg.sender).execTransactionFromModule( + address(hatsProtocol), + 0, + abi.encodeWithSignature( + "createHat(uint256,string,uint32,address,address,bool,string)", + adminHatId, + hat.details, + hat.maxSupply, + eligibilityAddress, + topHatAccount, + hat.isMutable, + hat.imageURI + ), + Enum.Operation.Call + ); + + // If the hat is termed, nominate the wearer as the eligible member + if (hat.termEndDateTs != 0) { + address[] memory nominatedWearers = new address[](1); + nominatedWearers[0] = hat.wearer; + + IAvatar(msg.sender).execTransactionFromModule( + eligibilityAddress, + 0, + abi.encodeWithSignature( + "elect(uint128,address[])", + hat.termEndDateTs, + nominatedWearers + ), + Enum.Operation.Call + ); + } + + IAvatar(msg.sender).execTransactionFromModule( + address(hatsProtocol), + 0, + abi.encodeWithSignature( + "mintHat(uint256,address)", + hatId, + hat.wearer + ), + Enum.Operation.Call + ); + return hatId; + } + + // Exists to avoid stack too deep errors + function _setupStreamRecipient( + IERC6551Registry registry, + address hatsAccountImplementation, + address hatsProtocol, + uint128 termEndDateTs, + address wearer, + uint256 hatId + ) private returns (address) { + // If the hat is termed, the wearer is the stream recipient + if (termEndDateTs != 0) { + return wearer; + } + + // Otherwise, the Hat's smart account is the stream recipient + return + registry.createAccount( + hatsAccountImplementation, + SALT, + block.chainid, + hatsProtocol, + hatId + ); + } + function _processSablierStreams( SablierStreamParams[] memory streamParams, address streamRecipient - ) internal { + ) private { for (uint256 i = 0; i < streamParams.length; ) { SablierStreamParams memory sablierStreamParams = streamParams[i]; diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index 2a3b2b4a..f48deeb1 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -4,7 +4,8 @@ pragma solidity =0.8.19; import {IHats} from "../interfaces/hats/full/IHats.sol"; contract MockHats is IHats { - uint256 public hatId = 0; + uint32 public lastTopHatId = 0; + uint256 public hatId = 1000; mapping(uint256 => address) public wearers; mapping(uint256 => address) public eligibility; @@ -15,9 +16,10 @@ contract MockHats is IHats { string memory, string memory ) external returns (uint256 topHatId) { - topHatId = hatId; - hatId++; + topHatId = ++lastTopHatId; wearers[topHatId] = _target; + wearers[hatId] = _target; + hatId++; } function createHat( diff --git a/test/DecentHatsCreationModule.test.ts b/test/DecentHatsCreationModule.test.ts index 982ca014..2889f903 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -229,7 +229,7 @@ describe('DecentHatsCreationModule', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '0'); + .withArgs(gnosisSafeAddress, 'topHatId', '1'); }); describe('Multiple calls', () => { @@ -283,26 +283,28 @@ describe('DecentHatsCreationModule', () => { it('Creates Top Hats with sequential IDs', async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '4'); + .withArgs(gnosisSafeAddress, 'topHatId', '2'); }); }); describe('Creating Hats Accounts', () => { it('Generates the correct Addresses for the current Hats', async () => { const currentCount = await mockHats.hatId(); - for (let i = 0n; i < currentCount; i++) { + for (let i = 1001n; i < currentCount; i++) { const hatAccount = await getHatAccount( i, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, ); + expect(await hatAccount.tokenId()).eq(i); expect(await hatAccount.tokenImplementation()).eq(mockHatsAddress); } }); }); }); + describe('Creating a new Top Hat and Tree with Termed Roles', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; @@ -372,7 +374,7 @@ describe('DecentHatsCreationModule', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '0'); + .withArgs(gnosisSafeAddress, 'topHatId', '1'); }); }); @@ -463,7 +465,7 @@ describe('DecentHatsCreationModule', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '0'); + .withArgs(gnosisSafeAddress, 'topHatId', '1'); }); it('Creates a Sablier stream for the hat with stream parameters', async () => { diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 194049ef..8b4f8691 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -23,7 +23,7 @@ import { } from '../typechain-types'; import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; -import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; +import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress, SALT } from './helpers'; describe('DecentHats_0_1_0', () => { let dao: SignerWithAddress; @@ -199,7 +199,7 @@ describe('DecentHats_0_1_0', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '0'); + .withArgs(gnosisSafeAddress, 'topHatId', '1'); }); describe('Multiple calls', () => { @@ -248,7 +248,7 @@ describe('DecentHats_0_1_0', () => { it('Creates Top Hats with sequential IDs', async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '4'); + .withArgs(gnosisSafeAddress, 'topHatId', '2'); }); }); @@ -256,7 +256,7 @@ describe('DecentHats_0_1_0', () => { it('Generates the correct Addresses for the current Hats', async () => { const currentCount = await mockHats.hatId(); - for (let i = 0n; i < currentCount; i++) { + for (let i = 1001n; i < currentCount; i++) { const topHatAccount = await getHatAccount( i, erc6551Registry, @@ -352,7 +352,7 @@ describe('DecentHats_0_1_0', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '0'); + .withArgs(gnosisSafeAddress, 'topHatId', '1'); }); it('Creates a Sablier stream for the hat with stream parameters', async () => { @@ -511,7 +511,7 @@ describe('DecentHats_0_1_0', () => { describe('Creating a new hat on existing Tree', () => { let createRoleHatPromise: Promise; - const topHatId = 0; + const topHatId = 1; beforeEach(async () => { await executeSafeTransaction({ @@ -544,6 +544,13 @@ describe('DecentHats_0_1_0', () => { const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + const topHatAccount = await getHatAccount( + BigInt(topHatId), + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress, + ); + createRoleHatPromise = executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, @@ -557,7 +564,7 @@ describe('DecentHats_0_1_0', () => { details: '', imageURI: '', isMutable: true, - wearer: '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + wearer: await topHatAccount.getAddress(), sablierParams: [ { sablier: mockSablierAddress, @@ -575,11 +582,11 @@ describe('DecentHats_0_1_0', () => { }, ], }, - 0, - '0xdce7ca0555101f97451926944f5ae3b7adb2f5ae', + topHatId, + await topHatAccount.getAddress(), await erc6551Registry.getAddress(), mockHatsAccountImplementationAddress, - '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072', + SALT, ], ), signers: [dao], @@ -622,12 +629,12 @@ describe('DecentHats_0_1_0', () => { await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); const hatsCountBeforeCreate = await mockHats.hatId(); - expect(hatsCountBeforeCreate).to.equal(2); // Top hat + admin hat + expect(hatsCountBeforeCreate).to.equal(1002); // Top hat + admin hat await createRoleHatPromise; const newHatId = await mockHats.hatId(); - expect(newHatId).to.equal(3); // + newly created hat + expect(newHatId).to.equal(1003); // + newly created hat }); }); }); diff --git a/test/helpers.ts b/test/helpers.ts index d8b42c2e..297dc69b 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -238,6 +238,8 @@ export const executeSafeTransaction = async ({ return tx; }; +export const SALT = '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072'; + export const getHatAccount = async ( hatId: bigint, erc6551RegistryImplementation: ERC6551Registry, @@ -245,11 +247,9 @@ export const getHatAccount = async ( mockHatsAddress: string, signer?: ethers.Signer, ) => { - const salt = '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072'; - const hatAccountAddress = await erc6551RegistryImplementation.account( mockHatsAccountImplementationAddress, - salt, + SALT, await hre.getChainId(), mockHatsAddress, hatId, From 313b448bc31bee0ab1e06ea3be98045ced721542 Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 30 Oct 2024 20:21:37 +0000 Subject: [PATCH 167/206] Add DecentHatsModificationModule --- contracts/DecentHatsModificationModule.sol | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 contracts/DecentHatsModificationModule.sol diff --git a/contracts/DecentHatsModificationModule.sol b/contracts/DecentHatsModificationModule.sol new file mode 100644 index 00000000..c0affb7f --- /dev/null +++ b/contracts/DecentHatsModificationModule.sol @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; +import {IHats} from "./interfaces/hats/full/IHats.sol"; +import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; +import {DecentHatsUtils} from "./DecentHatsUtils.sol"; + +contract DecentHatsModificationModule is DecentHatsUtils { + struct CreateTermedOrUntermedRoleHatParams { + IHats hatsProtocol; + IERC6551Registry registry; + address topHatAccount; + address hatsAccountImplementation; + uint256 adminHatId; + uint256 topHatId; + HatParams hat; + address hatsElectionsEligibilityImplementation; + IHatsModuleFactory hatsModuleFactory; + } + + /** + * @notice Creates a new termed or untermed role hat and any streams on it. + * + * @notice This contract should be enabled a module on the Safe for which the role is to be created, and disabled after. + * + * @dev Stream funds on untermed Roles are targeted at the hat's smart account. In order to withdraw funds from the stream, the + * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer. + * + * @dev Stream funds on termed Roles are targeted directly at the nominated wearer. + * The wearer should directly call `withdraw-` on the Sablier contract. + * + * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order + * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. + * See: https://github.com/decentdao/decent-interface/issues/2402 + */ + function createTestFobarrNewRoleHat( + CreateTermedOrUntermedRoleHatParams calldata params + ) external { + _processHat( + params.hatsProtocol, + params.registry, + params.hatsAccountImplementation, + params.topHatId, + params.topHatAccount, + params.hatsModuleFactory, + params.hatsElectionsEligibilityImplementation, + params.adminHatId, + params.hat + ); + } +} From 116d26a58fac28691b0a907f32766dbf03dd335e Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 19:46:34 -0400 Subject: [PATCH 168/206] Update the MockHats contract to more closely match the real Hats contract --- contracts/mocks/MockHats.sol | 1074 +++++++++++++++++++++++++++++++--- 1 file changed, 986 insertions(+), 88 deletions(-) diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index f48deeb1..c66fcf87 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -2,126 +2,770 @@ pragma solidity =0.8.19; import {IHats} from "../interfaces/hats/full/IHats.sol"; +import {IHatsIdUtilities} from "../interfaces/hats/full/IHatsIdUtilities.sol"; -contract MockHats is IHats { - uint32 public lastTopHatId = 0; - uint256 public hatId = 1000; - mapping(uint256 => address) public wearers; - mapping(uint256 => address) public eligibility; +/// @notice Minimalist and gas efficient standard ERC1155 implementation. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) +abstract contract ERC1155 { + /*////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////*/ - event HatCreated(uint256 hatId); + event TransferSingle( + address indexed operator, + address indexed from, + address indexed to, + uint256 id, + uint256 amount + ); - function mintTopHat( - address _target, - string memory, - string memory - ) external returns (uint256 topHatId) { - topHatId = ++lastTopHatId; - wearers[topHatId] = _target; - wearers[hatId] = _target; - hatId++; + event TransferBatch( + address indexed operator, + address indexed from, + address indexed to, + uint256[] ids, + uint256[] amounts + ); + + event ApprovalForAll( + address indexed owner, + address indexed operator, + bool approved + ); + + event URI(string value, uint256 indexed id); + + /*////////////////////////////////////////////////////////////// + ERC1155 STORAGE + //////////////////////////////////////////////////////////////*/ + + mapping(address => mapping(uint256 => uint256)) internal _balanceOf; + + mapping(address => mapping(address => bool)) public isApprovedForAll; + + /*////////////////////////////////////////////////////////////// + METADATA LOGIC + //////////////////////////////////////////////////////////////*/ + + function uri(uint256 id) public view virtual returns (string memory); + + /*////////////////////////////////////////////////////////////// + ERC1155 LOGIC + //////////////////////////////////////////////////////////////*/ + + function setApprovalForAll(address operator, bool approved) public virtual { + isApprovedForAll[msg.sender][operator] = approved; + + emit ApprovalForAll(msg.sender, operator, approved); } - function createHat( - uint256, - string calldata, - uint32, - address _eligibility, - address, - bool, - string calldata - ) external returns (uint256 newHatId) { - newHatId = hatId; - hatId++; - eligibility[hatId] = _eligibility; - emit HatCreated(hatId); + function safeTransferFrom( + address from, + address to, + uint256 id, + uint256 amount, + bytes calldata data + ) public virtual { + require( + msg.sender == from || isApprovedForAll[from][msg.sender], + "NOT_AUTHORIZED" + ); + + _balanceOf[from][id] -= amount; + _balanceOf[to][id] += amount; + + emit TransferSingle(msg.sender, from, to, id, amount); + + require( + to.code.length == 0 + ? to != address(0) + : ERC1155TokenReceiver(to).onERC1155Received( + msg.sender, + from, + id, + amount, + data + ) == ERC1155TokenReceiver.onERC1155Received.selector, + "UNSAFE_RECIPIENT" + ); } - function mintHat( - uint256 _hatId, - address _wearer - ) external returns (bool success) { - success = true; - wearers[_hatId] = _wearer; + function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data + ) public virtual { + require(ids.length == amounts.length, "LENGTH_MISMATCH"); + + require( + msg.sender == from || isApprovedForAll[from][msg.sender], + "NOT_AUTHORIZED" + ); + + // Storing these outside the loop saves ~15 gas per iteration. + uint256 id; + uint256 amount; + + for (uint256 i = 0; i < ids.length; ) { + id = ids[i]; + amount = amounts[i]; + + _balanceOf[from][id] -= amount; + _balanceOf[to][id] += amount; + + // An array can't have a total length + // larger than the max uint256 value. + unchecked { + ++i; + } + } + + emit TransferBatch(msg.sender, from, to, ids, amounts); + + require( + to.code.length == 0 + ? to != address(0) + : ERC1155TokenReceiver(to).onERC1155BatchReceived( + msg.sender, + from, + ids, + amounts, + data + ) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, + "UNSAFE_RECIPIENT" + ); } - function transferHat(uint256 _hatId, address _from, address _to) external { - require(wearers[_hatId] == _from, "MockHats: Invalid current wearer"); - wearers[_hatId] = _to; + function balanceOf( + address owner, + uint256 id + ) public view virtual returns (uint256 balance) { + balance = _balanceOf[owner][id]; } - function isWearerOfHat( - address _wearer, - uint256 _hatId - ) external view override returns (bool) { - return _wearer == wearers[_hatId]; + function balanceOfBatch( + address[] calldata owners, + uint256[] calldata ids + ) public view virtual returns (uint256[] memory balances) { + require(owners.length == ids.length, "LENGTH_MISMATCH"); + + balances = new uint256[](owners.length); + + // Unchecked because the only math done is incrementing + // the array index counter which cannot possibly overflow. + unchecked { + for (uint256 i = 0; i < owners.length; ++i) { + balances[i] = _balanceOf[owners[i]][ids[i]]; + } + } } - function getHatEligibilityModule( - uint256 _hatId - ) external view override returns (address) { - return eligibility[_hatId]; + /*////////////////////////////////////////////////////////////// + ERC165 LOGIC + //////////////////////////////////////////////////////////////*/ + + function supportsInterface( + bytes4 interfaceId + ) public view virtual returns (bool) { + return + interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 + interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 + interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } - function changeHatEligibility( - uint256 _hatId, - address _newEligibility - ) external override { - eligibility[_hatId] = _newEligibility; + /*////////////////////////////////////////////////////////////// + INTERNAL MINT/BURN LOGIC + //////////////////////////////////////////////////////////////*/ + + function _mint( + address to, + uint256 id, + uint256 amount, + bytes memory data + ) internal virtual { + _balanceOf[to][id] += amount; + + emit TransferSingle(msg.sender, address(0), to, id, amount); + + require( + to.code.length == 0 + ? to != address(0) + : ERC1155TokenReceiver(to).onERC1155Received( + msg.sender, + address(0), + id, + amount, + data + ) == ERC1155TokenReceiver.onERC1155Received.selector, + "UNSAFE_RECIPIENT" + ); + } + + function _batchMint( + address to, + uint256[] memory ids, + uint256[] memory amounts, + bytes memory data + ) internal virtual { + uint256 idsLength = ids.length; // Saves MLOADs. + + require(idsLength == amounts.length, "LENGTH_MISMATCH"); + + for (uint256 i = 0; i < idsLength; ) { + _balanceOf[to][ids[i]] += amounts[i]; + + // An array can't have a total length + // larger than the max uint256 value. + unchecked { + ++i; + } + } + + emit TransferBatch(msg.sender, address(0), to, ids, amounts); + + require( + to.code.length == 0 + ? to != address(0) + : ERC1155TokenReceiver(to).onERC1155BatchReceived( + msg.sender, + address(0), + ids, + amounts, + data + ) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, + "UNSAFE_RECIPIENT" + ); + } + + function _batchBurn( + address from, + uint256[] memory ids, + uint256[] memory amounts + ) internal virtual { + uint256 idsLength = ids.length; // Saves MLOADs. + + require(idsLength == amounts.length, "LENGTH_MISMATCH"); + + for (uint256 i = 0; i < idsLength; ) { + _balanceOf[from][ids[i]] -= amounts[i]; + + // An array can't have a total length + // larger than the max uint256 value. + unchecked { + ++i; + } + } + + emit TransferBatch(msg.sender, from, address(0), ids, amounts); + } + + function _burn(address from, uint256 id, uint256 amount) internal virtual { + _balanceOf[from][id] -= amount; + + emit TransferSingle(msg.sender, from, address(0), id, amount); + } +} + +/// @notice A generic interface for a contract which properly accepts ERC1155 tokens. +/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) +abstract contract ERC1155TokenReceiver { + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes calldata + ) external virtual returns (bytes4) { + return ERC1155TokenReceiver.onERC1155Received.selector; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) external virtual returns (bytes4) { + return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } +} + +/// @notice see HatsErrors.sol for description +error MaxLevelsReached(); + +/// @title Hats Id Utilities +/// @dev Functions for working with Hat Ids from Hats Protocol. Factored out of Hats.sol +/// for easier use by other contracts. +/// @author Haberdasher Labs +contract MockHatsIdUtilities is IHatsIdUtilities { + /// @notice Mapping of tophats requesting to link to admin hats in other trees + /// @dev Linkage only occurs if request is approved by the new admin + mapping(uint32 => uint256) public linkedTreeRequests; // topHatDomain => requested new admin + + /// @notice Mapping of approved & linked tophats to admin hats in other trees, used for grafting one hats tree onto another + /// @dev Trees can only be linked to another tree via their tophat + mapping(uint32 => uint256) public linkedTreeAdmins; // topHatDomain => hatId + + /** + * Hat Ids serve as addresses. A given Hat's Id represents its location in its + * hat tree: its level, its admin, its admin's admin (etc, all the way up to the + * tophat). + * + * The top level consists of 4 bytes and references all tophats. + * + * Each level below consists of 16 bits, and contains up to 65,536 child hats. + * + * A uint256 contains 4 bytes of space for tophat addresses, giving room for ((256 - + * 32) / 16) = 14 levels of delegation, with the admin at each level having space for + * 65,536 different child hats. + * + * A hat tree consists of a single tophat and has a max depth of 14 levels. + */ + + /// @dev Number of bits of address space for tophat ids, ie the tophat domain + uint256 internal constant TOPHAT_ADDRESS_SPACE = 32; + + /// @dev Number of bits of address space for each level below the tophat + uint256 internal constant LOWER_LEVEL_ADDRESS_SPACE = 16; + /// @dev Maximum number of levels below the tophat, ie max tree depth + /// (256 - TOPHAT_ADDRESS_SPACE) / LOWER_LEVEL_ADDRESS_SPACE; + uint256 internal constant MAX_LEVELS = 14; + + /// @notice Constructs a valid hat id for a new hat underneath a given admin + /// @dev Reverts if the admin has already reached `MAX_LEVELS` + /// @param _admin the id of the admin for the new hat + /// @param _newHat the uint16 id of the new hat + /// @return id The constructed hat id function buildHatId( uint256 _admin, uint16 _newHat - ) external pure override returns (uint256 id) {} + ) public pure returns (uint256 id) { + uint256 mask; + for (uint256 i = 0; i < MAX_LEVELS; ) { + unchecked { + mask = uint256( + type(uint256).max >> + // should not overflow given known constants + (TOPHAT_ADDRESS_SPACE + (LOWER_LEVEL_ADDRESS_SPACE * i)) + ); + } + if (_admin & mask == 0) { + unchecked { + id = + _admin | + (uint256(_newHat) << + // should not overflow given known constants + (LOWER_LEVEL_ADDRESS_SPACE * (MAX_LEVELS - 1 - i))); + } + return id; + } - function getHatLevel( - uint256 _hatId - ) external view override returns (uint32 level) {} + // should not overflow based on < MAX_LEVELS stopping condition + unchecked { + ++i; + } + } + + // if _admin is already at MAX_LEVELS, child hats are not possible, so we revert + revert MaxLevelsReached(); + } + + /// @notice Identifies the level a given hat in its hat tree + /// @param _hatId the id of the hat in question + /// @return level (0 to type(uint32).max) + function getHatLevel(uint256 _hatId) public view returns (uint32 level) { + // uint256 mask; + // uint256 i; + level = getLocalHatLevel(_hatId); + + uint256 treeAdmin = linkedTreeAdmins[getTopHatDomain(_hatId)]; + + if (treeAdmin != 0) { + level = 1 + level + getHatLevel(treeAdmin); + } + } + /// @notice Identifies the level a given hat in its local hat tree + /// @dev Similar to getHatLevel, but does not account for linked trees + /// @param _hatId the id of the hat in question + /// @return level The local level, from 0 to 14 function getLocalHatLevel( uint256 _hatId - ) external pure override returns (uint32 level) {} + ) public pure returns (uint32 level) { + if (_hatId & uint256(type(uint224).max) == 0) return 0; + if (_hatId & uint256(type(uint208).max) == 0) return 1; + if (_hatId & uint256(type(uint192).max) == 0) return 2; + if (_hatId & uint256(type(uint176).max) == 0) return 3; + if (_hatId & uint256(type(uint160).max) == 0) return 4; + if (_hatId & uint256(type(uint144).max) == 0) return 5; + if (_hatId & uint256(type(uint128).max) == 0) return 6; + if (_hatId & uint256(type(uint112).max) == 0) return 7; + if (_hatId & uint256(type(uint96).max) == 0) return 8; + if (_hatId & uint256(type(uint80).max) == 0) return 9; + if (_hatId & uint256(type(uint64).max) == 0) return 10; + if (_hatId & uint256(type(uint48).max) == 0) return 11; + if (_hatId & uint256(type(uint32).max) == 0) return 12; + if (_hatId & uint256(type(uint16).max) == 0) return 13; + return 14; + } - function isTopHat( - uint256 _hatId - ) external view override returns (bool _topHat) {} + /// @notice Checks whether a hat is a topHat + /// @param _hatId The hat in question + /// @return _isTopHat Whether the hat is a topHat + function isTopHat(uint256 _hatId) public view returns (bool _isTopHat) { + _isTopHat = + isLocalTopHat(_hatId) && + linkedTreeAdmins[getTopHatDomain(_hatId)] == 0; + } + /// @notice Checks whether a hat is a topHat in its local hat tree + /// @dev Similar to isTopHat, but does not account for linked trees + /// @param _hatId The hat in question + /// @return _isLocalTopHat Whether the hat is a topHat for its local tree function isLocalTopHat( uint256 _hatId - ) external pure override returns (bool _localTopHat) {} + ) public pure returns (bool _isLocalTopHat) { + _isLocalTopHat = _hatId > 0 && uint224(_hatId) == 0; + } function isValidHatId( uint256 _hatId - ) external view override returns (bool validHatId) {} + ) public pure returns (bool validHatId) { + // valid top hats are valid hats + if (isLocalTopHat(_hatId)) return true; + + uint32 level = getLocalHatLevel(_hatId); + uint256 admin; + // for each subsequent level up the tree, check if the level is 0 and return false if so + for (uint256 i = level - 1; i > 0; ) { + // truncate to find the (truncated) admin at this level + // we don't need to check _hatId's own level since getLocalHatLevel already ensures that its non-empty + admin = _hatId >> (LOWER_LEVEL_ADDRESS_SPACE * (MAX_LEVELS - i)); + // if the lowest level of the truncated admin is empty, the hat id is invalid + if (uint16(admin) == 0) return false; + unchecked { + --i; + } + } + // if there are no empty levels, return true + return true; + } + + /// @notice Gets the hat id of the admin at a given level of a given hat + /// @dev This function traverses trees by following the linkedTreeAdmin + /// pointer to a hat located in a different tree + /// @param _hatId the id of the hat in question + /// @param _level the admin level of interest + /// @return admin The hat id of the resulting admin function getAdminAtLevel( uint256 _hatId, uint32 _level - ) external view override returns (uint256 admin) {} + ) public view returns (uint256 admin) { + uint256 linkedTreeAdmin = linkedTreeAdmins[getTopHatDomain(_hatId)]; + if (linkedTreeAdmin == 0) + return admin = getAdminAtLocalLevel(_hatId, _level); + + uint32 localTopHatLevel = getHatLevel(getAdminAtLocalLevel(_hatId, 0)); + if (localTopHatLevel <= _level) + return + admin = getAdminAtLocalLevel(_hatId, _level - localTopHatLevel); + + return admin = getAdminAtLevel(linkedTreeAdmin, _level); + } + + /// @notice Gets the hat id of the admin at a given level of a given hat + /// local to the tree containing the hat. + /// @param _hatId the id of the hat in question + /// @param _level the admin level of interest + /// @return admin The hat id of the resulting admin function getAdminAtLocalLevel( uint256 _hatId, uint32 _level - ) external pure override returns (uint256 admin) {} + ) public pure returns (uint256 admin) { + uint256 mask = type(uint256).max << + (LOWER_LEVEL_ADDRESS_SPACE * (MAX_LEVELS - _level)); + + admin = _hatId & mask; + } + /// @notice Gets the tophat domain of a given hat + /// @dev A domain is the identifier for a given hat tree, stored in the first 4 bytes of a hat's id + /// @param _hatId the id of the hat in question + /// @return domain The domain of the hat's tophat function getTopHatDomain( uint256 _hatId - ) external view override returns (uint32 domain) {} + ) public pure returns (uint32 domain) { + domain = uint32(_hatId >> (LOWER_LEVEL_ADDRESS_SPACE * MAX_LEVELS)); + } + /// @notice Gets the domain of the highest parent tophat — the "tippy tophat" + /// @param _topHatDomain the 32 bit domain of a (likely linked) tophat + /// @return domain The tippy tophat domain function getTippyTopHatDomain( uint32 _topHatDomain - ) external view override returns (uint32 domain) {} + ) public view returns (uint32 domain) { + uint256 linkedAdmin = linkedTreeAdmins[_topHatDomain]; + if (linkedAdmin == 0) return domain = _topHatDomain; + return domain = getTippyTopHatDomain(getTopHatDomain(linkedAdmin)); + } + /// @notice Checks For any circular linkage of trees + /// @param _topHatDomain the 32 bit domain of the tree to be linked + /// @param _linkedAdmin the hatId of the potential tree admin + /// @return notCircular circular link has not been found function noCircularLinkage( uint32 _topHatDomain, uint256 _linkedAdmin - ) external view override returns (bool notCircular) {} + ) public view returns (bool notCircular) { + if (_linkedAdmin == 0) return true; + uint32 adminDomain = getTopHatDomain(_linkedAdmin); + if (_topHatDomain == adminDomain) return false; + uint256 parentAdmin = linkedTreeAdmins[adminDomain]; + return noCircularLinkage(_topHatDomain, parentAdmin); + } + /// @notice Checks that a tophat domain and its potential linked admin are from the same tree, ie have the same tippy tophat domain + /// @param _topHatDomain The 32 bit domain of the tophat to be linked + /// @param _newAdminHat The new admin for the linked tree + /// @return sameDomain Whether the _topHatDomain and the domain of its potential linked _newAdminHat domains are the same function sameTippyTopHatDomain( uint32 _topHatDomain, uint256 _newAdminHat - ) external view override returns (bool sameDomain) {} + ) public view returns (bool sameDomain) { + // get highest parent domains for current and new tree root admins + uint32 currentTippyTophatDomain = getTippyTopHatDomain(_topHatDomain); + uint32 newAdminDomain = getTopHatDomain(_newAdminHat); + uint32 newHTippyTophatDomain = getTippyTopHatDomain(newAdminDomain); + + // check that both domains are equal + sameDomain = (currentTippyTophatDomain == newHTippyTophatDomain); + } +} + +contract MockHats is IHats, ERC1155, MockHatsIdUtilities { + struct Hat { + // 1st storage slot + address eligibility; // ─┐ 20 + uint32 maxSupply; // │ 4 + uint32 supply; // │ 4 + uint16 lastHatId; // ─┘ 2 + // 2nd slot + address toggle; // ─┐ 20 + uint96 config; // ─┘ 12 + // 3rd+ slot (optional) + string details; + string imageURI; + } + + mapping(uint256 => Hat) internal _hats; + mapping(uint256 => mapping(address => bool)) public badStandings; + + uint32 public lastTopHatId; + + event HatCreated(uint256 hatId); + + function mintTopHat( + address _target, + string calldata _details, + string calldata _imageURI + ) external returns (uint256 topHatId) { + topHatId = uint256(++lastTopHatId) << 224; + + _createHat( + topHatId, + _details, // details + 1, // maxSupply = 1 + address(0), // there is no eligibility + address(0), // it has no toggle + false, // its immutable + _imageURI + ); + + _mintHat(_target, topHatId); + } + + function _mintHat(address _wearer, uint256 _hatId) internal { + unchecked { + // should not overflow since `mintHat` enforces max balance of 1 + _balanceOf[_wearer][_hatId] = 1; + + // increment Hat supply counter + // should not overflow given AllHatsWorn check in `mintHat` + ++_hats[_hatId].supply; + } + + emit TransferSingle(msg.sender, address(0), _wearer, _hatId, 1); + } + + function createHat( + uint256 _admin, + string calldata _details, + uint32 _maxSupply, + address _eligibility, + address _toggle, + bool _mutable, + string calldata _imageURI + ) public returns (uint256 newHatId) { + if (uint16(_admin) > 0) { + revert MaxLevelsReached(); + } + + if (_eligibility == address(0)) revert ZeroAddress(); + if (_toggle == address(0)) revert ZeroAddress(); + // check that the admin id is valid, ie does not contain empty levels between filled levels + if (!isValidHatId(_admin)) revert InvalidHatId(); + // construct the next hat id + newHatId = getNextId(_admin); + // to create a hat, you must be wearing one of its admin hats + _checkAdmin(newHatId); + // create the new hat + _createHat( + newHatId, + _details, + _maxSupply, + _eligibility, + _toggle, + _mutable, + _imageURI + ); + // increment _admin.lastHatId + // use the overflow check to constrain to correct number of hats per level + ++_hats[_admin].lastHatId; + } + + function getNextId(uint256 _admin) public view returns (uint256 nextId) { + uint16 nextHatId = _hats[_admin].lastHatId + 1; + nextId = buildHatId(_admin, nextHatId); + } + + function getNextIdOffset( + uint256 _admin, + uint8 _offset + ) public view returns (uint256 nextId) { + uint16 nextHatId = _hats[_admin].lastHatId + 1 + _offset; + nextId = buildHatId(_admin, nextHatId); + } + + function _createHat( + uint256 _id, + string calldata _details, + uint32 _maxSupply, + address _eligibility, + address _toggle, + bool _mutable, + string calldata _imageURI + ) internal { + /* + We write directly to storage instead of first building the Hat struct in memory. + This allows us to cheaply use the existing lastHatId value in case it was incremented by creating a hat while skipping admin levels. + (Resetting it to 0 would be bad since this hat's child hat(s) would overwrite the previously created hat(s) at that level.) + */ + Hat storage hat = _hats[_id]; + hat.details = _details; + hat.maxSupply = _maxSupply; + hat.eligibility = _eligibility; + hat.toggle = _toggle; + hat.imageURI = _imageURI; + // config is a concatenation of the status and mutability properties + hat.config = _mutable ? uint96(3 << 94) : uint96(1 << 95); + + emit HatCreated( + _id, + _details, + _maxSupply, + _eligibility, + _toggle, + _mutable, + _imageURI + ); + } + + function mintHat( + uint256 _hatId, + address _wearer + ) public returns (bool success) { + Hat storage hat = _hats[_hatId]; + if (hat.maxSupply == 0) revert HatDoesNotExist(_hatId); + // only eligible wearers can receive minted hats + if (!isEligible(_wearer, _hatId)) revert NotEligible(); + // only active hats can be minted + if (!_isActive(hat, _hatId)) revert HatNotActive(); + // only the wearer of one of a hat's admins can mint it + _checkAdmin(_hatId); + // hat supply cannot exceed maxSupply + if (hat.supply >= hat.maxSupply) revert AllHatsWorn(_hatId); + // wearers cannot wear the same hat more than once + if (_staticBalanceOf(_wearer, _hatId) > 0) + revert AlreadyWearingHat(_wearer, _hatId); + // if we've made it through all the checks, mint the hat + _mintHat(_wearer, _hatId); + + success = true; + } + + function transferHat(uint256 _hatId, address _from, address _to) public { + _checkAdmin(_hatId); + // cannot transfer immutable hats, except for tophats, which can always transfer themselves + if (!isTopHat(_hatId)) { + if (!_isMutable(_hats[_hatId])) revert Immutable(); + } + // Checks storage instead of `isWearerOfHat` since admins may want to transfer revoked Hats to new wearers + if (_staticBalanceOf(_from, _hatId) < 1) revert NotHatWearer(); + // Check if recipient is already wearing hat; also checks storage to maintain balance == 1 invariant + if (_staticBalanceOf(_to, _hatId) > 0) + revert AlreadyWearingHat(_to, _hatId); + // only eligible wearers can receive transferred hats + if (!isEligible(_to, _hatId)) revert NotEligible(); + // only active hats can be transferred + if (!_isActive(_hats[_hatId], _hatId)) revert HatNotActive(); + // we've made it passed all the checks, so adjust balances to execute the transfer + _balanceOf[_from][_hatId] = 0; + _balanceOf[_to][_hatId] = 1; + // emit the ERC1155 standard transfer event + emit TransferSingle(msg.sender, _from, _to, _hatId, 1); + } + + function _staticBalanceOf( + address _account, + uint256 _hatId + ) internal view returns (uint256 staticBalance) { + staticBalance = _balanceOf[_account][_hatId]; + } + + function _isMutable( + Hat storage _hat + ) internal view returns (bool _mutable) { + _mutable = (_hat.config & uint96(1 << 94) != 0); + } + + function getHatEligibilityModule( + uint256 _hatId + ) external view returns (address eligibility) { + eligibility = _hats[_hatId].eligibility; + } + + function changeHatEligibility( + uint256 _hatId, + address _newEligibility + ) external { + if (_newEligibility == address(0)) revert ZeroAddress(); + + _checkAdmin(_hatId); + Hat storage hat = _hats[_hatId]; + + if (!_isMutable(hat)) { + revert Immutable(); + } + + hat.eligibility = _newEligibility; + + emit HatEligibilityChanged(_hatId, _newEligibility); + } function batchCreateHats( uint256[] calldata _admins, @@ -133,12 +777,6 @@ contract MockHats is IHats { string[] calldata _imageURIs ) external override returns (bool success) {} - function getNextId( - uint256 - ) external view override returns (uint256 nextId) { - nextId = hatId; - } - function batchMintHats( uint256[] calldata _hatIds, address[] calldata _wearers @@ -162,11 +800,88 @@ contract MockHats is IHats { function checkHatWearerStatus( uint256 _hatId, - address - ) external override returns (bool updated) { - // 'burns' the hat if the wearer is no longer eligible - wearers[_hatId] = address(0); - return true; + address _wearer + ) public returns (bool updated) { + bool eligible; + bool standing; + + (bool success, bytes memory returndata) = _hats[_hatId] + .eligibility + .staticcall( + abi.encodeWithSignature( + "getWearerStatus(address,uint256)", + _wearer, + _hatId + ) + ); + + /* + * if function call succeeds with data of length == 64, then we know the contract exists + * and has the getWearerStatus function (which returns two words). + * But — since function selectors don't include return types — we still can't assume that the return data is two booleans, + * so we treat it as a uint so it will always safely decode without throwing. + */ + if (success && returndata.length == 64) { + // check the returndata manually + (uint256 firstWord, uint256 secondWord) = abi.decode( + returndata, + (uint256, uint256) + ); + // returndata is valid + if (firstWord < 2 && secondWord < 2) { + standing = (secondWord == 1) ? true : false; + // never eligible if in bad standing + eligible = (standing && firstWord == 1) ? true : false; + } + // returndata is invalid + else { + revert NotHatsEligibility(); + } + } else { + revert NotHatsEligibility(); + } + + updated = _processHatWearerStatus(_hatId, _wearer, eligible, standing); + } + + function _processHatWearerStatus( + uint256 _hatId, + address _wearer, + bool _eligible, + bool _standing + ) internal returns (bool updated) { + // revoke/burn the hat if _wearer has a positive balance + if (_staticBalanceOf(_wearer, _hatId) > 0) { + // always ineligible if in bad standing + if (!_eligible || !_standing) { + _burnHat(_wearer, _hatId); + } + } + + // record standing for use by other contracts + // note: here, standing and badStandings are opposite + // i.e. if standing (true = good standing) + // then badStandings[_hatId][wearer] will be false + // if they are different, then something has changed, and we need to update + // badStandings marker + if (_standing == badStandings[_hatId][_wearer]) { + badStandings[_hatId][_wearer] = !_standing; + updated = true; + + emit WearerStandingChanged(_hatId, _wearer, _standing); + } + } + + function _burnHat(address _wearer, uint256 _hatId) internal { + // neither should underflow since `_burnHat` is never called on non-positive balance + unchecked { + _balanceOf[_wearer][_hatId] = 0; + + // decrement Hat supply counter + --_hats[_hatId].supply; + } + + emit TransferSingle(msg.sender, _wearer, address(0), _hatId, 1); } function renounceHat(uint256 _hatId) external override {} @@ -240,11 +955,6 @@ contract MockHats is IHats { ) {} - function isAdminOfHat( - address _user, - uint256 _hatId - ) external view override returns (bool isAdmin) {} - function isInGoodStanding( address _wearer, uint256 _hatId @@ -253,7 +963,9 @@ contract MockHats is IHats { function isEligible( address _wearer, uint256 _hatId - ) external view override returns (bool eligible) {} + ) public view returns (bool eligible) { + eligible = _isEligible(_wearer, _hats[_hatId], _hatId); + } function getHatToggleModule( uint256 _hatId @@ -274,14 +986,200 @@ contract MockHats is IHats { function balanceOf( address _wearer, uint256 _hatId - ) external view override returns (uint256 balance) {} + ) public view override(ERC1155, IHats) returns (uint256 balance) { + Hat storage hat = _hats[_hatId]; + + balance = 0; + + if (_isActive(hat, _hatId) && _isEligible(_wearer, hat, _hatId)) { + balance = super.balanceOf(_wearer, _hatId); + } + } function balanceOfBatch( address[] calldata _wearers, uint256[] calldata _hatIds - ) external view override returns (uint256[] memory) {} + ) public view override(ERC1155, IHats) returns (uint256[] memory balances) { + if (_wearers.length != _hatIds.length) + revert BatchArrayLengthMismatch(); + + balances = new uint256[](_wearers.length); + + // Unchecked because the only math done is incrementing + // the array index counter which cannot possibly overflow. + unchecked { + for (uint256 i; i < _wearers.length; ++i) { + balances[i] = balanceOf(_wearers[i], _hatIds[i]); + } + } + } function uri( - uint256 id - ) external view override returns (string memory _uri) {} + uint256 + ) public pure override(ERC1155, IHats) returns (string memory _uri) { + _uri = ""; + } + + /// @notice Checks whether msg.sender is an admin of a hat, and reverts if not + function _checkAdmin(uint256 _hatId) internal view { + if (!isAdminOfHat(msg.sender, _hatId)) { + revert NotAdmin(msg.sender, _hatId); + } + } + + /// @notice Checks whether a given address serves as the admin of a given Hat + /// @dev Recursively checks if `_user` wears the admin Hat of the Hat in question. This is recursive since there may be a string of Hats as admins of Hats. + /// @param _user The address in question + /// @param _hatId The id of the Hat for which the `_user` might be the admin + /// @return isAdmin Whether the `_user` has admin rights for the Hat + function isAdminOfHat( + address _user, + uint256 _hatId + ) public view returns (bool isAdmin) { + uint256 linkedTreeAdmin; + uint32 adminLocalHatLevel; + if (isLocalTopHat(_hatId)) { + linkedTreeAdmin = linkedTreeAdmins[getTopHatDomain(_hatId)]; + if (linkedTreeAdmin == 0) { + // tree is not linked + return isAdmin = isWearerOfHat(_user, _hatId); + } else { + // tree is linked + if (isWearerOfHat(_user, linkedTreeAdmin)) { + return isAdmin = true; + } + // user wears the treeAdmin + else { + adminLocalHatLevel = getLocalHatLevel(linkedTreeAdmin); + _hatId = linkedTreeAdmin; + } + } + } else { + // if we get here, _hatId is not a tophat of any kind + // get the local tree level of _hatId's admin + adminLocalHatLevel = getLocalHatLevel(_hatId) - 1; + } + + // search up _hatId's local address space for an admin hat that the _user wears + while (adminLocalHatLevel > 0) { + if ( + isWearerOfHat( + _user, + getAdminAtLocalLevel(_hatId, adminLocalHatLevel) + ) + ) { + return isAdmin = true; + } + // should not underflow given stopping condition > 0 + unchecked { + --adminLocalHatLevel; + } + } + + // if we get here, we've reached the top of _hatId's local tree, ie the local tophat + // check if the user wears the local tophat + if (isWearerOfHat(_user, getAdminAtLocalLevel(_hatId, 0))) + return isAdmin = true; + + // if not, we check if it's linked to another tree + linkedTreeAdmin = linkedTreeAdmins[getTopHatDomain(_hatId)]; + if (linkedTreeAdmin == 0) { + // tree is not linked + // we've already learned that user doesn't wear the local tophat, so there's nothing else to check; we return false + return isAdmin = false; + } else { + // tree is linked + // check if user is wearer of linkedTreeAdmin + if (isWearerOfHat(_user, linkedTreeAdmin)) return true; + // if not, recurse to traverse the parent tree for a hat that the user wears + isAdmin = isAdminOfHat(_user, linkedTreeAdmin); + } + } + + function isWearerOfHat( + address _user, + uint256 _hatId + ) public view returns (bool isWearer) { + isWearer = (balanceOf(_user, _hatId) > 0); + } + + function _isActive( + Hat storage _hat, + uint256 _hatId + ) internal view returns (bool active) { + (bool success, bytes memory returndata) = _hat.toggle.staticcall( + abi.encodeWithSignature("getHatStatus(uint256)", _hatId) + ); + + /* + * if function call succeeds with data of length == 32, then we know the contract exists + * and has the getHatStatus function. + * But — since function selectors don't include return types — we still can't assume that the return data is a boolean, + * so we treat it as a uint so it will always safely decode without throwing. + */ + if (success && returndata.length == 32) { + // check the returndata manually + uint256 uintReturndata = uint256(bytes32(returndata)); + // false condition + if (uintReturndata == 0) { + active = false; + // true condition + } else if (uintReturndata == 1) { + active = true; + } + // invalid condition + else { + active = _getHatStatus(_hat); + } + } else { + active = _getHatStatus(_hat); + } + } + + function _isEligible( + address _wearer, + Hat storage _hat, + uint256 _hatId + ) internal view returns (bool eligible) { + (bool success, bytes memory returndata) = _hat.eligibility.staticcall( + abi.encodeWithSignature( + "getWearerStatus(address,uint256)", + _wearer, + _hatId + ) + ); + + /* + * if function call succeeds with data of length == 64, then we know the contract exists + * and has the getWearerStatus function (which returns two words). + * But — since function selectors don't include return types — we still can't assume that the return data is two booleans, + * so we treat it as a uint so it will always safely decode without throwing. + */ + if (success && returndata.length == 64) { + bool standing; + // check the returndata manually + (uint256 firstWord, uint256 secondWord) = abi.decode( + returndata, + (uint256, uint256) + ); + // returndata is valid + if (firstWord < 2 && secondWord < 2) { + standing = (secondWord == 1) ? true : false; + // never eligible if in bad standing + eligible = (standing && firstWord == 1) ? true : false; + } + // returndata is invalid + else { + eligible = !badStandings[_hatId][_wearer]; + } + } else { + eligible = !badStandings[_hatId][_wearer]; + } + } + + function _getHatStatus( + Hat storage _hat + ) internal view returns (bool status) { + status = (_hat.config >> 95 != 0); + } } From 05895ec2a325a2eefbcb7c98da048687b531cab4 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 19:46:52 -0400 Subject: [PATCH 169/206] Add helper function to convert a human readable top hat integer to the real hatid --- test/helpers.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/helpers.ts b/test/helpers.ts index 297dc69b..9e3bbb3c 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -262,3 +262,13 @@ export const getHatAccount = async ( return hatAccount; }; + +export const topHatIdToHatId = (topHatId: bigint): bigint => { + // Ensure the input is valid (fits within uint32) + if (topHatId <= 0 || topHatId > 0xffffffff) { + throw new Error('Top hat ID must be a positive integer that fits within uint32'); + } + + // Shift left by 224 bits (same as in Solidity) + return topHatId << 224n; +}; From 007161cfed84926833f1c71b8800fcb8ccfd1149 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 19:47:52 -0400 Subject: [PATCH 170/206] Fix the top hat id generation in DecentHatsCreationModule --- contracts/DecentHatsCreationModule.sol | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index 7c68dfda..8dcb2402 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -118,12 +118,11 @@ contract DecentHatsCreationModule is DecentHatsUtils { address keyValuePairs, TopHatParams memory topHat ) internal returns (uint256 topHatId, address topHatAccount) { - (, bytes memory lastTopHatId) = address(hatsProtocol).call( + (bool success, bytes memory lastTopHatId) = address(hatsProtocol).call( abi.encodeWithSignature("lastTopHatId()") ); - - // topHatId = abi.decode(lastTopHatId, (uint256)) << 224; - topHatId = uint256(bytes32(lastTopHatId)) + 1; + require(success, "Failed to get lastTopHatId"); + topHatId = uint256(uint32(bytes4(lastTopHatId)) + 1) << 224; IAvatar(msg.sender).execTransactionFromModule( // Mint top hat to the safe From 62ecffa69ae17f1257beaedd224164a9eaa0fffa Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 20:07:58 -0400 Subject: [PATCH 171/206] Fix tests --- test/DecentAutonomousAdmin.test.ts | 29 ++--- test/DecentHatsCreationModule.test.ts | 67 +++++++++--- test/DecentHats_0_1_0.test.ts | 121 +++++++++++++++------ test/DecentSablierStreamManagement.test.ts | 17 ++- 4 files changed, 169 insertions(+), 65 deletions(-) diff --git a/test/DecentAutonomousAdmin.test.ts b/test/DecentAutonomousAdmin.test.ts index 5f009833..1a1b965e 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/DecentAutonomousAdmin.test.ts @@ -9,6 +9,7 @@ import { MockHatsElectionsEligibility, MockHatsElectionsEligibility__factory, } from '../typechain-types'; +import { topHatIdToHatId } from './helpers'; describe('DecentAutonomousAdminHat', function () { // Signer accounts @@ -35,18 +36,21 @@ describe('DecentAutonomousAdminHat', function () { // Deploy MockHatsElectionEligibility (Eligibility Module) hatsElectionModule = await new MockHatsElectionsEligibility__factory(deployer).deploy(); + const topHatId = topHatIdToHatId((await hatsProtocol.lastTopHatId()) + 1n); + await hatsProtocol.mintTopHat(deployer.address, 'Details', 'imageURI'); + + const adminHatId = await hatsProtocol.getNextId(topHatId); + // Create Admin Hat - const createAdminTx = await hatsProtocol.createHat( - hre.ethers.ZeroAddress, // Admin address (self-administered), currently unused + await hatsProtocol.createHat( + topHatId, // top hat id 'Details', // Hat details 100, // Max supply - hre.ethers.ZeroAddress, // Eligibility module (none) - hre.ethers.ZeroAddress, // Toggle module (none) + '0x0000000000000000000000000000000000004a75', // Eligibility module (none) + '0x0000000000000000000000000000000000004a75', // Toggle module (none) true, // Is mutable 'imageURI', // Image URI ); - const createAdminTxReceipt = await createAdminTx.wait(); - const adminHatId = createAdminTxReceipt?.toJSON().logs[0].args[0]; // Deploy DecentAutonomousAdminHat contract with the admin hat ID decentAutonomousAdminInstance = await new DecentAutonomousAdmin__factory(deployer).deploy(); @@ -54,20 +58,19 @@ describe('DecentAutonomousAdminHat', function () { // Mint the admin hat to adminHatWearer await hatsProtocol.mintHat(adminHatId, adminHatAddress); + userHatId = await hatsProtocol.getNextId(adminHatId); + // Create User Hat under the admin hat - const createUserTx = await hatsProtocol.createHat( - hre.ethers.ZeroAddress, // Admin address (decentAutonomousAdminInstance contract), currently unused + await hatsProtocol.createHat( + adminHatId, // Admin hat id 'Details', // Hat details 100, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) - hre.ethers.ZeroAddress, // Toggle module (none) + '0x0000000000000000000000000000000000004a75', // Toggle module (none) false, // Is mutable 'imageURI', // Image URI ); - const createUserTxReceipt = await createUserTx.wait(); - userHatId = createUserTxReceipt?.toJSON().logs[0].args[0]; - // Mint the user hat to currentWearer await hatsProtocol.mintHat(userHatId, await currentWearer.getAddress()); }); @@ -75,7 +78,7 @@ describe('DecentAutonomousAdminHat', function () { describe('triggerStartNextTerm', function () { it('should correctly validate current wearer and transfer', async function () { const args = { - currentWearer: currentWearer.address, + currentWearer: await currentWearer.getAddress(), hatsProtocol: await hatsProtocol.getAddress(), hatId: userHatId, nominatedWearer: nominatedWearer.address, diff --git a/test/DecentHatsCreationModule.test.ts b/test/DecentHatsCreationModule.test.ts index 2889f903..c1ea79ef 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -30,7 +30,12 @@ import { } from '../typechain-types'; import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; -import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; +import { + executeSafeTransaction, + getHatAccount, + predictGnosisSafeAddress, + topHatIdToHatId, +} from './helpers'; describe('DecentHatsCreationModule', () => { let dao: SignerWithAddress; @@ -161,10 +166,23 @@ describe('DecentHatsCreationModule', () => { }); describe('Creating a new Top Hat and Tree', () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + let createAndDeclareTreeTx1: ethers.ContractTransactionResponse; + + let topHatId: bigint; + let adminHatId: bigint; + let roleHatIds: bigint[]; beforeEach(async () => { - createAndDeclareTreeTx = await executeSafeTransaction({ + const lastTopHatId = await mockHats.lastTopHatId(); + const thisTopHatId = lastTopHatId + 1n; + topHatId = topHatIdToHatId(thisTopHatId); + adminHatId = await mockHats.getNextId(topHatId); + roleHatIds = [ + await mockHats.getNextId(adminHatId), + await mockHats.getNextIdOffset(adminHatId, 1), + ]; + + createAndDeclareTreeTx1 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsCreationModuleAddress, transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( @@ -217,25 +235,34 @@ describe('DecentHatsCreationModule', () => { }); it('Emits an ExecutionSuccess event', async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); + await expect(createAndDeclareTreeTx1).to.emit(gnosisSafe, 'ExecutionSuccess'); }); it('Emits an ExecutionFromModuleSuccess event', async () => { - await expect(createAndDeclareTreeTx) + await expect(createAndDeclareTreeTx1) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentHatsCreationModuleAddress); }); + it('Leaves the Hats contract with a correct lastTopHatId', async () => { + expect(await mockHats.lastTopHatId()).to.equal(1n); + }); + it('Emits some hatsTreeId ValueUpdated events', async () => { - await expect(createAndDeclareTreeTx) + await expect(createAndDeclareTreeTx1) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '1'); + .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); }); describe('Multiple calls', () => { let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; + let secondTopHatId: bigint; beforeEach(async () => { + const lastTopHatId = await mockHats.lastTopHatId(); + const thisTopHatId = lastTopHatId + 1n; + secondTopHatId = topHatIdToHatId(thisTopHatId); + createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsCreationModuleAddress, @@ -280,25 +307,31 @@ describe('DecentHatsCreationModule', () => { .withArgs(decentHatsCreationModuleAddress); }); - it('Creates Top Hats with sequential IDs', async () => { + it('Leaves the Hats contract with a correct lastTopHatId', async () => { + expect(await mockHats.lastTopHatId()).to.equal(2n); + }); + + // TODO: This is failing and I don't know why + it.skip('Creates Top Hats with different IDs', async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '2'); + .withArgs(gnosisSafeAddress, 'topHatId', secondTopHatId.toString()); }); }); describe('Creating Hats Accounts', () => { it('Generates the correct Addresses for the current Hats', async () => { - const currentCount = await mockHats.hatId(); - for (let i = 1001n; i < currentCount; i++) { + const allHatsIds = [topHatId, adminHatId, ...roleHatIds]; + + for (const hatId of allHatsIds) { const hatAccount = await getHatAccount( - i, + hatId, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, ); - expect(await hatAccount.tokenId()).eq(i); + expect(await hatAccount.tokenId()).eq(hatId); expect(await hatAccount.tokenImplementation()).eq(mockHatsAddress); } }); @@ -307,8 +340,10 @@ describe('DecentHatsCreationModule', () => { describe('Creating a new Top Hat and Tree with Termed Roles', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + let topHatId: bigint; beforeEach(async () => { + topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsCreationModuleAddress, @@ -374,15 +409,17 @@ describe('DecentHatsCreationModule', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '1'); + .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); }); }); describe('Creating a new Top Hat and Tree with Sablier Streams', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; let currentBlockTimestamp: number; + let topHatId: bigint; beforeEach(async () => { + topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; createAndDeclareTreeTx = await executeSafeTransaction({ @@ -465,7 +502,7 @@ describe('DecentHatsCreationModule', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '1'); + .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); }); it('Creates a Sablier stream for the hat with stream parameters', async () => { diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts index 8b4f8691..08a347ad 100644 --- a/test/DecentHats_0_1_0.test.ts +++ b/test/DecentHats_0_1_0.test.ts @@ -23,7 +23,13 @@ import { } from '../typechain-types'; import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; -import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress, SALT } from './helpers'; +import { + executeSafeTransaction, + getHatAccount, + predictGnosisSafeAddress, + SALT, + topHatIdToHatId, +} from './helpers'; describe('DecentHats_0_1_0', () => { let dao: SignerWithAddress; @@ -139,7 +145,18 @@ describe('DecentHats_0_1_0', () => { describe('Creating a new Top Hat and Tree', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; + let topHatId: bigint; + let adminHatId: bigint; + let roleHatIds: bigint[]; + beforeEach(async () => { + topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); + adminHatId = await mockHats.getNextId(topHatId); + roleHatIds = [ + await mockHats.getNextId(adminHatId), + await mockHats.getNextIdOffset(adminHatId, 1), + ]; + createAndDeclareTreeTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, @@ -199,13 +216,15 @@ describe('DecentHats_0_1_0', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '1'); + .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); }); describe('Multiple calls', () => { let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; + let newTopHatId: bigint; beforeEach(async () => { + newTopHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, @@ -245,27 +264,31 @@ describe('DecentHats_0_1_0', () => { .withArgs(decentHatsAddress); }); - it('Creates Top Hats with sequential IDs', async () => { + it('Leaves the Hats contract with a correct lastTopHatId', async () => { + expect(await mockHats.lastTopHatId()).to.equal(2n); + }); + + it('Creates Top Hats with different IDs', async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '2'); + .withArgs(gnosisSafeAddress, 'topHatId', newTopHatId.toString()); }); }); describe('Creating Hats Accounts', () => { it('Generates the correct Addresses for the current Hats', async () => { - const currentCount = await mockHats.hatId(); + const allHatsIds = [topHatId, adminHatId, ...roleHatIds]; - for (let i = 1001n; i < currentCount; i++) { - const topHatAccount = await getHatAccount( - i, + for (const hatId of allHatsIds) { + const hatAccount = await getHatAccount( + hatId, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, ); - expect(await topHatAccount.tokenId()).eq(i); - expect(await topHatAccount.tokenImplementation()).eq(mockHatsAddress); + expect(await hatAccount.tokenId()).eq(hatId); + expect(await hatAccount.tokenImplementation()).eq(mockHatsAddress); } }); }); @@ -274,8 +297,10 @@ describe('DecentHats_0_1_0', () => { describe('Creating a new Top Hat and Tree with Sablier Streams', () => { let createAndDeclareTreeTx: ethers.ContractTransactionResponse; let currentBlockTimestamp: number; + let topHatId: bigint; beforeEach(async () => { + topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; createAndDeclareTreeTx = await executeSafeTransaction({ @@ -352,7 +377,7 @@ describe('DecentHats_0_1_0', () => { it('Emits some hatsTreeId ValueUpdated events', async () => { await expect(createAndDeclareTreeTx) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', '1'); + .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); }); it('Creates a Sablier stream for the hat with stream parameters', async () => { @@ -510,10 +535,28 @@ describe('DecentHats_0_1_0', () => { }); describe('Creating a new hat on existing Tree', () => { - let createRoleHatPromise: Promise; - const topHatId = 1; + let topHatAccount: MockHatsAccount; + let currentBlockTimestamp: number; + let topHatId: bigint; + let adminHatId: bigint; + let createNewHatData: { + safe: GnosisSafeL2; + to: string; + transactionData: string; + signers: SignerWithAddress[]; + }; + let transferTopHatData: { + safe: GnosisSafeL2; + to: string; + transactionData: string; + signers: SignerWithAddress[]; + }; beforeEach(async () => { + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); + adminHatId = await mockHats.getNextId(topHatId); + await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, @@ -542,29 +585,27 @@ describe('DecentHats_0_1_0', () => { signers: [dao], }); - const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - - const topHatAccount = await getHatAccount( - BigInt(topHatId), + topHatAccount = await getHatAccount( + topHatId, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, ); - createRoleHatPromise = executeSafeTransaction({ + createNewHatData = { safe: gnosisSafe, to: decentHatsAddress, transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( 'createRoleHat', [ mockHatsAddress, - 1, + adminHatId, { maxSupply: 1, details: '', imageURI: '', isMutable: true, - wearer: await topHatAccount.getAddress(), + wearer: await topHatAccount.getAddress(), // any non-zero address sablierParams: [ { sablier: mockSablierAddress, @@ -590,35 +631,48 @@ describe('DecentHats_0_1_0', () => { ], ), signers: [dao], - }); + }; + transferTopHatData = { + safe: gnosisSafe, + to: mockHatsAddress, + transactionData: MockHats__factory.createInterface().encodeFunctionData('transferHat', [ + topHatId, + gnosisSafeAddress, + decentHatsAddress, + ]), + signers: [dao], + }; }); it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { - await expect(createRoleHatPromise).to.be.reverted; + await expect(executeSafeTransaction(createNewHatData)).to.be.reverted; }); it('Emits an ExecutionSuccess event', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); - await expect(await createRoleHatPromise).to.emit(gnosisSafe, 'ExecutionSuccess'); + await executeSafeTransaction(transferTopHatData); + await expect(executeSafeTransaction(createNewHatData)).to.emit( + gnosisSafe, + 'ExecutionSuccess', + ); }); it('Emits an ExecutionFromModuleSuccess event', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); - await expect(await createRoleHatPromise) + await executeSafeTransaction(transferTopHatData); + await expect(executeSafeTransaction(createNewHatData)) .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') .withArgs(decentHatsAddress); }); it('Transfers the top hat back to the Safe', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await executeSafeTransaction(transferTopHatData); const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); expect(isModuleWearerOfTopHat).to.equal(true); - await createRoleHatPromise; + await executeSafeTransaction(createNewHatData); const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); expect(isSafeWearerOfTopHat).to.equal(true); @@ -626,15 +680,14 @@ describe('DecentHats_0_1_0', () => { it('Actually creates the new hat', async () => { // First transfer the top hat to the Safe - await mockHats.transferHat(topHatId, gnosisSafeAddress, decentHatsAddress); + await executeSafeTransaction(transferTopHatData); - const hatsCountBeforeCreate = await mockHats.hatId(); - expect(hatsCountBeforeCreate).to.equal(1002); // Top hat + admin hat + const nextHatIdBeforeCreatingNewHats = await mockHats.getNextId(adminHatId); - await createRoleHatPromise; + await executeSafeTransaction(createNewHatData); - const newHatId = await mockHats.hatId(); - expect(newHatId).to.equal(1003); // + newly created hat + const nextHatIdAfterCreatingNewHats = await mockHats.getNextId(adminHatId); + expect(nextHatIdAfterCreatingNewHats).to.not.equal(nextHatIdBeforeCreatingNewHats); }); }); }); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 360eaa4a..71c5ef94 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -24,7 +24,12 @@ import { } from '../typechain-types'; import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from './GlobalSafeDeployments.test'; -import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress } from './helpers'; +import { + executeSafeTransaction, + getHatAccount, + predictGnosisSafeAddress, + topHatIdToHatId, +} from './helpers'; describe('DecentSablierStreamManagement', () => { let dao: SignerWithAddress; @@ -60,6 +65,8 @@ describe('DecentSablierStreamManagement', () => { let createAndDeclareTreeWithRolesAndStreamsTx: ethers.ContractTransactionResponse; const streamFundsMax = ethers.parseEther('100'); + let roleHatId: bigint; + beforeEach(async () => { const signers = await hre.ethers.getSigners(); const [deployer] = signers; @@ -136,6 +143,10 @@ describe('DecentSablierStreamManagement', () => { let keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); + const topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); + const adminHatId = await mockHats.getNextId(topHatId); + roleHatId = await mockHats.getNextId(adminHatId); + createAndDeclareTreeWithRolesAndStreamsTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, @@ -237,7 +248,7 @@ describe('DecentSablierStreamManagement', () => { expect(await mockSablier.withdrawableAmountOf(streamId)).to.eq(streamFundsMax); const recipientHatAccount = await getHatAccount( - 2n, + roleHatId, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, @@ -282,7 +293,7 @@ describe('DecentSablierStreamManagement', () => { await hre.ethers.provider.send('evm_mine', []); const recipientHatAccount = await getHatAccount( - 2n, + roleHatId, erc6551Registry, mockHatsAccountImplementationAddress, mockHatsAddress, From bbfe421db4b517f285215428cee86f4d8697e8ba Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 30 Oct 2024 20:12:49 -0400 Subject: [PATCH 172/206] Remove unused imports from DecentHatsUtils --- contracts/DecentHatsUtils.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/DecentHatsUtils.sol b/contracts/DecentHatsUtils.sol index d1cd89fe..84367641 100644 --- a/contracts/DecentHatsUtils.sol +++ b/contracts/DecentHatsUtils.sol @@ -3,14 +3,11 @@ pragma solidity 0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; import {IHats} from "./interfaces/hats/full/IHats.sol"; import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; -import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; -import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; contract DecentHatsUtils { From 4b7e36fafc683f930dc1ce2c5fc67841580832a8 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 09:48:26 -0400 Subject: [PATCH 173/206] Was decoding the low level call to Hats Contract incorrectly --- contracts/DecentHatsCreationModule.sol | 5 +++-- test/DecentHatsCreationModule.test.ts | 11 ++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index 8dcb2402..27fb22d1 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -118,11 +118,12 @@ contract DecentHatsCreationModule is DecentHatsUtils { address keyValuePairs, TopHatParams memory topHat ) internal returns (uint256 topHatId, address topHatAccount) { - (bool success, bytes memory lastTopHatId) = address(hatsProtocol).call( + // Call lastTopHatId() and properly decode the response + (bool success, bytes memory data) = address(hatsProtocol).call( abi.encodeWithSignature("lastTopHatId()") ); require(success, "Failed to get lastTopHatId"); - topHatId = uint256(uint32(bytes4(lastTopHatId)) + 1) << 224; + topHatId = (abi.decode(data, (uint256)) + 1) << 224; IAvatar(msg.sender).execTransactionFromModule( // Mint top hat to the safe diff --git a/test/DecentHatsCreationModule.test.ts b/test/DecentHatsCreationModule.test.ts index c1ea79ef..ee07de64 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/DecentHatsCreationModule.test.ts @@ -256,12 +256,10 @@ describe('DecentHatsCreationModule', () => { describe('Multiple calls', () => { let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; - let secondTopHatId: bigint; + let newTopHatId: bigint; beforeEach(async () => { - const lastTopHatId = await mockHats.lastTopHatId(); - const thisTopHatId = lastTopHatId + 1n; - secondTopHatId = topHatIdToHatId(thisTopHatId); + newTopHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); createAndDeclareTreeTx2 = await executeSafeTransaction({ safe: gnosisSafe, @@ -311,11 +309,10 @@ describe('DecentHatsCreationModule', () => { expect(await mockHats.lastTopHatId()).to.equal(2n); }); - // TODO: This is failing and I don't know why - it.skip('Creates Top Hats with different IDs', async () => { + it('Creates Top Hats with different IDs', async () => { await expect(createAndDeclareTreeTx2) .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', secondTopHatId.toString()); + .withArgs(gnosisSafeAddress, 'topHatId', newTopHatId.toString()); }); }); From d38bb745bfa889715b674fc9aed27bfde3344e4b Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 10:39:33 -0400 Subject: [PATCH 174/206] MockHats is now pretty much exacty like Hats --- contracts/mocks/MockHats.sol | 1336 ++++++++++++++++++++++++++++------ 1 file changed, 1098 insertions(+), 238 deletions(-) diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index c66fcf87..886b9c72 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -294,6 +294,7 @@ abstract contract ERC1155TokenReceiver { /// @notice see HatsErrors.sol for description error MaxLevelsReached(); +error InvalidUnlink(); /// @title Hats Id Utilities /// @dev Functions for working with Hat Ids from Hats Protocol. Factored out of Hats.sol @@ -548,6 +549,29 @@ contract MockHatsIdUtilities is IHatsIdUtilities { } contract MockHats is IHats, ERC1155, MockHatsIdUtilities { + /// @notice This contract's version is labeled v1. Previous versions labeled similarly as v1 and v1.0 are deprecated, + /// and should be treated as beta deployments. + + /*////////////////////////////////////////////////////////////// + HATS DATA MODELS + //////////////////////////////////////////////////////////////*/ + + /// @notice A Hat object containing the hat's properties + /// @dev The members are packed to minimize storage costs + /// @custom:member eligibility Module that rules on wearer eligibiliy and standing + /// @custom:member maxSupply The max number of hats with this id that can exist + /// @custom:member supply The number of this hat that currently exist + /// @custom:member lastHatId Indexes how many different child hats an admin has + /// @custom:member toggle Module that sets the hat's status + /** + * @custom:member config Holds status and other settings, with this bitwise schema: + * + * 0th bit | `active` status; can be altered by toggle + * 1 | `mutable` setting + * 2 - 95 | unassigned + */ + /// @custom:member details Holds arbitrary metadata about the hat + /// @custom:member imageURI A uri pointing to an image for the hat struct Hat { // 1st storage slot address eligibility; // ─┐ 20 @@ -562,18 +586,57 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { string imageURI; } - mapping(uint256 => Hat) internal _hats; + /*////////////////////////////////////////////////////////////// + HATS STORAGE + //////////////////////////////////////////////////////////////*/ + + /// @notice The name of the contract, typically including the version + string public name; + + /// @notice The first 4 bytes of the id of the last tophat created. + uint32 public lastTopHatId; // first tophat id starts at 1 + + /// @notice The fallback image URI for hat tokens with no `imageURI` specified in their branch + string public baseImageURI; + + /// @dev Internal mapping of hats to hat ids. See HatsIdUtilities.sol for more info on how hat ids work + mapping(uint256 => Hat) internal _hats; // key: hatId => value: Hat struct + + /// @notice Mapping of wearers in bad standing for certain hats + /// @dev Used by external contracts to trigger penalties for wearers in bad standing + /// hatId => wearer => !standing mapping(uint256 => mapping(address => bool)) public badStandings; - uint32 public lastTopHatId; + /*////////////////////////////////////////////////////////////// + CONSTRUCTOR + //////////////////////////////////////////////////////////////*/ + + /// @notice All arguments are immutable; they can only be set once during construction + constructor() { + name = "MockHats"; + baseImageURI = ""; + } - event HatCreated(uint256 hatId); + /*////////////////////////////////////////////////////////////// + HATS LOGIC + //////////////////////////////////////////////////////////////*/ + /// @notice Creates and mints a Hat that is its own admin, i.e. a "topHat" + /// @dev A topHat has no eligibility and no toggle + /// @param _target The address to which the newly created topHat is minted + /// @param _details A description of the Hat [optional]. Should not be larger than 7000 bytes + /// (enforced in changeHatDetails) + /// @param _imageURI The image uri for this top hat and the fallback for its + /// downstream hats [optional]. Should not be large than 7000 bytes + /// (enforced in changeHatImageURI) + /// @return topHatId The id of the newly created topHat function mintTopHat( address _target, string calldata _details, string calldata _imageURI - ) external returns (uint256 topHatId) { + ) public returns (uint256 topHatId) { + // create hat + topHatId = uint256(++lastTopHatId) << 224; _createHat( @@ -589,19 +652,17 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { _mintHat(_target, topHatId); } - function _mintHat(address _wearer, uint256 _hatId) internal { - unchecked { - // should not overflow since `mintHat` enforces max balance of 1 - _balanceOf[_wearer][_hatId] = 1; - - // increment Hat supply counter - // should not overflow given AllHatsWorn check in `mintHat` - ++_hats[_hatId].supply; - } - - emit TransferSingle(msg.sender, address(0), _wearer, _hatId, 1); - } - + /// @notice Creates a new hat. The msg.sender must wear the `_admin` hat. + /// @dev Initializes a new Hat struct, but does not mint any tokens. + /// @param _details A description of the Hat. Should not be larger than 7000 bytes (enforced in changeHatDetails) + /// @param _maxSupply The total instances of the Hat that can be worn at once + /// @param _admin The id of the Hat that will control who wears the newly created hat + /// @param _eligibility The address that can report on the Hat wearer's status + /// @param _toggle The address that can deactivate the Hat + /// @param _mutable Whether the hat's properties are changeable after creation + /// @param _imageURI The image uri for this hat and the fallback for its + /// downstream hats [optional]. Should not be larger than 7000 bytes (enforced in changeHatImageURI) + /// @return newHatId The id of the newly created Hat function createHat( uint256 _admin, string calldata _details, @@ -638,11 +699,74 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { ++_hats[_admin].lastHatId; } + /// @notice Creates new hats in batch. The msg.sender must be an admin of each hat. + /// @dev This is a convenience function that loops through the arrays and calls `createHat`. + /// @param _admins Array of ids of admins for each hat to create + /// @param _details Array of details for each hat to create + /// @param _maxSupplies Array of supply caps for each hat to create + /// @param _eligibilityModules Array of eligibility module addresses for each hat to + /// create + /// @param _toggleModules Array of toggle module addresses for each hat to create + /// @param _mutables Array of mutable flags for each hat to create + /// @param _imageURIs Array of imageURIs for each hat to create + /// @return success True if all createHat calls succeeded + function batchCreateHats( + uint256[] calldata _admins, + string[] calldata _details, + uint32[] calldata _maxSupplies, + address[] memory _eligibilityModules, + address[] memory _toggleModules, + bool[] calldata _mutables, + string[] calldata _imageURIs + ) public returns (bool success) { + // check if array lengths are the same + uint256 length = _admins.length; // save an MLOAD + + { + bool sameLengths = (length == _details.length && // details + length == _maxSupplies.length && // supplies + length == _eligibilityModules.length && // eligibility + length == _toggleModules.length && // toggle + length == _mutables.length && // mutable + length == _imageURIs.length); // imageURI + if (!sameLengths) revert BatchArrayLengthMismatch(); + } + + // loop through and create each hat + for (uint256 i = 0; i < length; ) { + createHat( + _admins[i], + _details[i], + _maxSupplies[i], + _eligibilityModules[i], + _toggleModules[i], + _mutables[i], + _imageURIs[i] + ); + + unchecked { + ++i; + } + } + + success = true; + } + + /// @notice Gets the id of the next child hat of the hat `_admin` + /// @dev Does not incrememnt lastHatId + /// @param _admin The id of the hat to serve as the admin for the next child hat + /// @return nextId The new hat id function getNextId(uint256 _admin) public view returns (uint256 nextId) { uint16 nextHatId = _hats[_admin].lastHatId + 1; nextId = buildHatId(_admin, nextHatId); } + /// @notice Gets the id of the next child hat of the hat `_admin` with an offset + /// @dev Does not incrememnt lastHatId + /// @dev This is for testing purposes + /// @param _admin The id of the hat to serve as the admin for the next child hat + /// @param _offset The offset to apply to the lastHatId + /// @return nextId The new hat id function getNextIdOffset( uint256 _admin, uint8 _offset @@ -651,40 +775,11 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { nextId = buildHatId(_admin, nextHatId); } - function _createHat( - uint256 _id, - string calldata _details, - uint32 _maxSupply, - address _eligibility, - address _toggle, - bool _mutable, - string calldata _imageURI - ) internal { - /* - We write directly to storage instead of first building the Hat struct in memory. - This allows us to cheaply use the existing lastHatId value in case it was incremented by creating a hat while skipping admin levels. - (Resetting it to 0 would be bad since this hat's child hat(s) would overwrite the previously created hat(s) at that level.) - */ - Hat storage hat = _hats[_id]; - hat.details = _details; - hat.maxSupply = _maxSupply; - hat.eligibility = _eligibility; - hat.toggle = _toggle; - hat.imageURI = _imageURI; - // config is a concatenation of the status and mutability properties - hat.config = _mutable ? uint96(3 << 94) : uint96(1 << 95); - - emit HatCreated( - _id, - _details, - _maxSupply, - _eligibility, - _toggle, - _mutable, - _imageURI - ); - } - + /// @notice Mints an ERC1155-similar token of the Hat to an eligible recipient, who then "wears" the hat + /// @dev The msg.sender must wear an admin Hat of `_hatId`, and the recipient must be eligible to wear `_hatId` + /// @param _hatId The id of the Hat to mint + /// @param _wearer The address to which the Hat is minted + /// @return success Whether the mint succeeded function mintHat( uint256 _hatId, address _wearer @@ -708,96 +803,132 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { success = true; } - function transferHat(uint256 _hatId, address _from, address _to) public { - _checkAdmin(_hatId); - // cannot transfer immutable hats, except for tophats, which can always transfer themselves - if (!isTopHat(_hatId)) { - if (!_isMutable(_hats[_hatId])) revert Immutable(); - } - // Checks storage instead of `isWearerOfHat` since admins may want to transfer revoked Hats to new wearers - if (_staticBalanceOf(_from, _hatId) < 1) revert NotHatWearer(); - // Check if recipient is already wearing hat; also checks storage to maintain balance == 1 invariant - if (_staticBalanceOf(_to, _hatId) > 0) - revert AlreadyWearingHat(_to, _hatId); - // only eligible wearers can receive transferred hats - if (!isEligible(_to, _hatId)) revert NotEligible(); - // only active hats can be transferred - if (!_isActive(_hats[_hatId], _hatId)) revert HatNotActive(); - // we've made it passed all the checks, so adjust balances to execute the transfer - _balanceOf[_from][_hatId] = 0; - _balanceOf[_to][_hatId] = 1; - // emit the ERC1155 standard transfer event - emit TransferSingle(msg.sender, _from, _to, _hatId, 1); - } - - function _staticBalanceOf( - address _account, - uint256 _hatId - ) internal view returns (uint256 staticBalance) { - staticBalance = _balanceOf[_account][_hatId]; - } + /// @notice Mints new hats in batch. The msg.sender must be an admin of each hat. + /// @dev This is a convenience function that loops through the arrays and calls `mintHat`. + /// @param _hatIds Array of ids of hats to mint + /// @param _wearers Array of addresses to which the hats will be minted + /// @return success True if all mintHat calls succeeded + function batchMintHats( + uint256[] calldata _hatIds, + address[] calldata _wearers + ) public returns (bool success) { + uint256 length = _hatIds.length; + if (length != _wearers.length) revert BatchArrayLengthMismatch(); - function _isMutable( - Hat storage _hat - ) internal view returns (bool _mutable) { - _mutable = (_hat.config & uint96(1 << 94) != 0); - } + for (uint256 i = 0; i < length; ) { + mintHat(_hatIds[i], _wearers[i]); + unchecked { + ++i; + } + } - function getHatEligibilityModule( - uint256 _hatId - ) external view returns (address eligibility) { - eligibility = _hats[_hatId].eligibility; + success = true; } - function changeHatEligibility( + /// @notice Toggles a Hat's status from active to deactive, or vice versa + /// @dev The msg.sender must be set as the hat's toggle + /// @param _hatId The id of the Hat for which to adjust status + /// @param _newStatus The new status to set + /// @return toggled Whether the status was toggled + function setHatStatus( uint256 _hatId, - address _newEligibility - ) external { - if (_newEligibility == address(0)) revert ZeroAddress(); - - _checkAdmin(_hatId); + bool _newStatus + ) external returns (bool toggled) { Hat storage hat = _hats[_hatId]; - if (!_isMutable(hat)) { - revert Immutable(); + if (msg.sender != hat.toggle) { + revert NotHatsToggle(); } - hat.eligibility = _newEligibility; - - emit HatEligibilityChanged(_hatId, _newEligibility); + toggled = _processHatStatus(_hatId, _newStatus); } - function batchCreateHats( - uint256[] calldata _admins, - string[] calldata _details, - uint32[] calldata _maxSupplies, - address[] memory _eligibilityModules, - address[] memory _toggleModules, - bool[] calldata _mutables, - string[] calldata _imageURIs - ) external override returns (bool success) {} + /// @notice Checks a hat's toggle module and processes the returned status + /// @dev May change the hat's status in storage + /// @param _hatId The id of the Hat whose toggle we are checking + /// @return toggled Whether there was a new status + function checkHatStatus(uint256 _hatId) public returns (bool toggled) { + Hat storage hat = _hats[_hatId]; - function batchMintHats( - uint256[] calldata _hatIds, - address[] calldata _wearers - ) external override returns (bool success) {} + // attempt to retrieve the hat's status from the toggle module + (bool success, bool newStatus) = _pullHatStatus(hat, _hatId); - function setHatStatus( - uint256 _hatId, - bool _newStatus - ) external override returns (bool toggled) {} + // if unsuccessful (ie toggle was humanistic), process the new status + if (!success) revert NotHatsToggle(); + + // if successful (ie toggle was mechanistic), process the new status + toggled = _processHatStatus(_hatId, newStatus); + } - function checkHatStatus( + function _pullHatStatus( + Hat storage _hat, uint256 _hatId - ) external override returns (bool toggled) {} + ) internal view returns (bool success, bool newStatus) { + bytes memory data = abi.encodeWithSignature( + "getHatStatus(uint256)", + _hatId + ); + bytes memory returndata; + (success, returndata) = _hat.toggle.staticcall(data); + + /* + * if function call succeeds with data of length == 32, then we know the contract exists + * and has the getHatStatus function. + * But — since function selectors don't include return types — we still can't assume that the return data is a boolean, + * so we treat it as a uint so it will always safely decode without throwing. + */ + if (success && returndata.length == 32) { + // check the returndata manually + uint256 uintReturndata = abi.decode(returndata, (uint256)); + // false condition + if (uintReturndata == 0) { + newStatus = false; + // true condition + } else if (uintReturndata == 1) { + newStatus = true; + } + // invalid condition + else { + success = false; + } + } else { + success = false; + } + } + /// @notice Report from a hat's eligibility on the status of one of its wearers and, if `false`, revoke their hat + /// @dev Burns the wearer's hat, if revoked + /// @param _hatId The id of the hat + /// @param _wearer The address of the hat wearer whose status is being reported + /// @param _eligible Whether the wearer is eligible for the hat (will be revoked if + /// false) + /// @param _standing False if the wearer is no longer in good standing (and potentially should be penalized) + /// @return updated Whether the report succeeded function setHatWearerStatus( uint256 _hatId, address _wearer, bool _eligible, bool _standing - ) external override returns (bool updated) {} + ) external returns (bool updated) { + Hat storage hat = _hats[_hatId]; + + if (msg.sender != hat.eligibility) { + revert NotHatsEligibility(); + } + + updated = _processHatWearerStatus( + _hatId, + _wearer, + _eligible, + _standing + ); + } + /// @notice Check a hat's eligibility for a report on the status of one of the hat's wearers and, if `false`, revoke their hat + /// @dev Burns the wearer's hat, if revoked + /// @param _hatId The id of the hat + /// @param _wearer The address of the Hat wearer whose status report is being requested + /// @return updated Whether the wearer's status was altered function checkHatWearerStatus( uint256 _hatId, address _wearer @@ -844,6 +975,93 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { updated = _processHatWearerStatus(_hatId, _wearer, eligible, standing); } + /// @notice Stop wearing a hat, aka "renounce" it + /// @dev Burns the msg.sender's hat + /// @param _hatId The id of the Hat being renounced + function renounceHat(uint256 _hatId) external { + if (_staticBalanceOf(msg.sender, _hatId) < 1) { + revert NotHatWearer(); + } + // remove the hat + _burnHat(msg.sender, _hatId); + } + + /*////////////////////////////////////////////////////////////// + HATS INTERNAL LOGIC + //////////////////////////////////////////////////////////////*/ + + /// @notice Internal call for creating a new hat + /// @dev Initializes a new Hat in storage, but does not mint any tokens + /// @param _id ID of the hat to be stored + /// @param _details A description of the hat + /// @param _maxSupply The total instances of the Hat that can be worn at once + /// @param _eligibility The address that can report on the Hat wearer's status + /// @param _toggle The address that can deactivate the hat [optional] + /// @param _mutable Whether the hat's properties are changeable after creation + /// @param _imageURI The image uri for this top hat and the fallback for its + /// downstream hats [optional] + function _createHat( + uint256 _id, + string calldata _details, + uint32 _maxSupply, + address _eligibility, + address _toggle, + bool _mutable, + string calldata _imageURI + ) internal { + /* + We write directly to storage instead of first building the Hat struct in memory. + This allows us to cheaply use the existing lastHatId value in case it was incremented by creating a hat while skipping admin levels. + (Resetting it to 0 would be bad since this hat's child hat(s) would overwrite the previously created hat(s) at that level.) + */ + Hat storage hat = _hats[_id]; + hat.details = _details; + hat.maxSupply = _maxSupply; + hat.eligibility = _eligibility; + hat.toggle = _toggle; + hat.imageURI = _imageURI; + // config is a concatenation of the status and mutability properties + hat.config = _mutable ? uint96(3 << 94) : uint96(1 << 95); + + emit HatCreated( + _id, + _details, + _maxSupply, + _eligibility, + _toggle, + _mutable, + _imageURI + ); + } + + /// @notice Internal function to process hat status + /// @dev Updates a hat's status if different from current + /// @param _hatId The id of the Hat in quest + /// @param _newStatus The status to potentially change to + /// @return updated - Whether the status was updated + function _processHatStatus( + uint256 _hatId, + bool _newStatus + ) internal returns (bool updated) { + // optimize later + Hat storage hat = _hats[_hatId]; + + if (_newStatus != _getHatStatus(hat)) { + _setHatStatus(hat, _newStatus); + emit HatStatusChanged(_hatId, _newStatus); + updated = true; + } + } + + /// @notice Internal call to process wearer status from the eligibility module + /// @dev Burns the wearer's Hat token if _eligible is false, and updates badStandings + /// state if necessary + /// @param _hatId The id of the Hat to revoke + /// @param _wearer The address of the wearer in question + /// @param _eligible Whether _wearer is eligible for the Hat (if false, this function + /// will revoke their Hat) + /// @param _standing Whether _wearer is in good standing (to be recorded in storage) + /// @return updated Whether the wearer standing was updated function _processHatWearerStatus( uint256 _hatId, address _wearer, @@ -872,61 +1090,327 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { } } - function _burnHat(address _wearer, uint256 _hatId) internal { - // neither should underflow since `_burnHat` is never called on non-positive balance - unchecked { - _balanceOf[_wearer][_hatId] = 0; - - // decrement Hat supply counter - --_hats[_hatId].supply; + /// @notice Internal function to set a hat's status in storage + /// @dev Flips the 0th bit of _hat.config via bitwise operation + /// @param _hat The hat object + /// @param _status The status to set for the hat + function _setHatStatus(Hat storage _hat, bool _status) internal { + if (_status) { + _hat.config |= uint96(1 << 95); + } else { + _hat.config &= ~uint96(1 << 95); } - - emit TransferSingle(msg.sender, _wearer, address(0), _hatId, 1); } - function renounceHat(uint256 _hatId) external override {} - - function makeHatImmutable(uint256 _hatId) external override {} - - function changeHatDetails( + /** + * @notice Internal function to retrieve an account's internal "static" balance directly from internal storage, + * @dev This function bypasses the dynamic `_isActive` and `_isEligible` checks + * @param _account The account to check + * @param _hatId The hat to check + * @return staticBalance The account's static of the hat, from internal storage + */ + function _staticBalanceOf( + address _account, + uint256 _hatId + ) internal view returns (uint256 staticBalance) { + staticBalance = _balanceOf[_account][_hatId]; + } + + /*////////////////////////////////////////////////////////////// + HATS ADMIN FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + /// @notice Checks whether msg.sender is an admin of a hat, and reverts if not + function _checkAdmin(uint256 _hatId) internal view { + if (!isAdminOfHat(msg.sender, _hatId)) { + revert NotAdmin(msg.sender, _hatId); + } + } + + /// @notice checks whether the msg.sender is either an admin or wearer or a hat, and reverts the appropriate error if not + function _checkAdminOrWearer(uint256 _hatId) internal view { + if ( + !isAdminOfHat(msg.sender, _hatId) && + !isWearerOfHat(msg.sender, _hatId) + ) { + revert NotAdminOrWearer(); + } + } + + /// @notice Transfers a hat from one wearer to another eligible wearer + /// @dev The hat must be mutable, and the transfer must be initiated by an admin + /// @param _hatId The hat in question + /// @param _from The current wearer + /// @param _to The new wearer + function transferHat(uint256 _hatId, address _from, address _to) public { + _checkAdmin(_hatId); + // cannot transfer immutable hats, except for tophats, which can always transfer themselves + if (!isTopHat(_hatId)) { + if (!_isMutable(_hats[_hatId])) revert Immutable(); + } + // Checks storage instead of `isWearerOfHat` since admins may want to transfer revoked Hats to new wearers + if (_staticBalanceOf(_from, _hatId) < 1) revert NotHatWearer(); + // Check if recipient is already wearing hat; also checks storage to maintain balance == 1 invariant + if (_staticBalanceOf(_to, _hatId) > 0) + revert AlreadyWearingHat(_to, _hatId); + // only eligible wearers can receive transferred hats + if (!isEligible(_to, _hatId)) revert NotEligible(); + // only active hats can be transferred + if (!_isActive(_hats[_hatId], _hatId)) revert HatNotActive(); + // we've made it passed all the checks, so adjust balances to execute the transfer + _balanceOf[_from][_hatId] = 0; + _balanceOf[_to][_hatId] = 1; + // emit the ERC1155 standard transfer event + emit TransferSingle(msg.sender, _from, _to, _hatId, 1); + } + + /// @notice Set a mutable hat to immutable + /// @dev Sets the second bit of hat.config to 0 + /// @param _hatId The id of the Hat to make immutable + function makeHatImmutable(uint256 _hatId) external { + _checkAdmin(_hatId); + + Hat storage hat = _hats[_hatId]; + + if (!_isMutable(hat)) { + revert Immutable(); + } + + hat.config &= ~uint96(1 << 94); + + emit HatMutabilityChanged(_hatId); + } + + /// @notice Change a hat's details + /// @dev Hat must be mutable, except for tophats. + /// @param _hatId The id of the Hat to change + /// @param _newDetails The new details. Must not be larger than 7000 bytes. + function changeHatDetails( uint256 _hatId, - string memory _newDetails - ) external override {} + string calldata _newDetails + ) external { + if (bytes(_newDetails).length > 7000) revert StringTooLong(); + + _checkAdmin(_hatId); + + Hat storage hat = _hats[_hatId]; - function changeHatToggle( + // a tophat can change its own details, but otherwise only mutable hat details can be changed + if (!isTopHat(_hatId)) { + if (!_isMutable(hat)) revert Immutable(); + } + + hat.details = _newDetails; + + emit HatDetailsChanged(_hatId, _newDetails); + } + + /// @notice Change a hat's details + /// @dev Hat must be mutable + /// @param _hatId The id of the Hat to change + /// @param _newEligibility The new eligibility module + function changeHatEligibility( uint256 _hatId, - address _newToggle - ) external override {} + address _newEligibility + ) external { + if (_newEligibility == address(0)) revert ZeroAddress(); + + _checkAdmin(_hatId); + Hat storage hat = _hats[_hatId]; + + if (!_isMutable(hat)) { + revert Immutable(); + } + hat.eligibility = _newEligibility; + + emit HatEligibilityChanged(_hatId, _newEligibility); + } + + /// @notice Change a hat's details + /// @dev Hat must be mutable + /// @param _hatId The id of the Hat to change + /// @param _newToggle The new toggle module + function changeHatToggle(uint256 _hatId, address _newToggle) external { + if (_newToggle == address(0)) revert ZeroAddress(); + + _checkAdmin(_hatId); + Hat storage hat = _hats[_hatId]; + + if (!_isMutable(hat)) { + revert Immutable(); + } + + // record hat status from old toggle before changing; ensures smooth transition to new toggle, + // especially in case of switching from mechanistic to humanistic toggle + // a) attempt to retrieve hat status from old toggle + (bool success, bool newStatus) = _pullHatStatus(hat, _hatId); + // b) if succeeded, (ie if old toggle was mechanistic), store the retrieved status + if (success) _processHatStatus(_hatId, newStatus); + + // set the new toggle + hat.toggle = _newToggle; + + emit HatToggleChanged(_hatId, _newToggle); + } + + /// @notice Change a hat's details + /// @dev Hat must be mutable, except for tophats + /// @param _hatId The id of the Hat to change + /// @param _newImageURI The new imageURI. Must not be larger than 7000 bytes. function changeHatImageURI( uint256 _hatId, - string memory _newImageURI - ) external override {} + string calldata _newImageURI + ) external { + if (bytes(_newImageURI).length > 7000) revert StringTooLong(); - function changeHatMaxSupply( - uint256 _hatId, - uint32 _newMaxSupply - ) external override {} + _checkAdmin(_hatId); + Hat storage hat = _hats[_hatId]; + + // a tophat can change its own imageURI, but otherwise only mutable hat imageURIs can be changed + if (!isTopHat(_hatId)) { + if (!_isMutable(hat)) revert Immutable(); + } + + hat.imageURI = _newImageURI; + + emit HatImageURIChanged(_hatId, _newImageURI); + } + + /// @notice Change a hat's details + /// @dev Hat must be mutable; new max supply cannot be less than current supply + /// @param _hatId The id of the Hat to change + /// @param _newMaxSupply The new max supply + function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external { + _checkAdmin(_hatId); + Hat storage hat = _hats[_hatId]; + + if (!_isMutable(hat)) { + revert Immutable(); + } + + if (_newMaxSupply < hat.supply) { + revert NewMaxSupplyTooLow(); + } + + if (_newMaxSupply != hat.maxSupply) { + hat.maxSupply = _newMaxSupply; + emit HatMaxSupplyChanged(_hatId, _newMaxSupply); + } + } + /// @notice Submits a request to link a Hat Tree under a parent tree. Requests can be + /// submitted by either... + /// a) the wearer of a topHat, previous to any linkage, or + /// b) the admin(s) of an already-linked topHat (aka tree root), where such a + /// request is to move the tree root to another admin within the same parent + /// tree + /// @dev A topHat can have at most 1 request at a time. Submitting a new request will + /// replace the existing request. + /// @param _topHatDomain The domain of the topHat to link + /// @param _requestedAdminHat The hat that will administer the linked tree function requestLinkTopHatToTree( - uint32 _topHatId, - uint256 _newAdminHat - ) external override {} + uint32 _topHatDomain, + uint256 _requestedAdminHat + ) external { + uint256 fullTopHatId = uint256(_topHatDomain) << 224; // (256 - TOPHAT_ADDRESS_SPACE); + + // The wearer of an unlinked tophat is also the admin of same; once a tophat is linked, its wearer is no longer its admin + _checkAdmin(fullTopHatId); + + linkedTreeRequests[_topHatDomain] = _requestedAdminHat; + emit TopHatLinkRequested(_topHatDomain, _requestedAdminHat); + } + /// @notice Approve a request to link a Tree under a parent tree, with options to add eligibility or toggle modules and change its metadata + /// @dev Requests can only be approved by wearer or an admin of the `_newAdminHat`, and there + /// can only be one link per tree root at a given time. + /// @param _topHatDomain The 32 bit domain of the topHat to link + /// @param _newAdminHat The hat that will administer the linked tree + /// @param _eligibility Optional new eligibility module for the linked topHat + /// @param _toggle Optional new toggle module for the linked topHat + /// @param _details Optional new details for the linked topHat + /// @param _imageURI Optional new imageURI for the linked topHat function approveLinkTopHatToTree( - uint32 _topHatId, + uint32 _topHatDomain, uint256 _newAdminHat, address _eligibility, address _toggle, string calldata _details, string calldata _imageURI - ) external override {} + ) external { + // for everything but the last hat level, check the admin of `_newAdminHat`'s theoretical child hat, since either wearer or admin of `_newAdminHat` can approve + if (getHatLevel(_newAdminHat) < MAX_LEVELS) { + _checkAdmin(buildHatId(_newAdminHat, 1)); + } else { + // the above buildHatId trick doesn't work for the last hat level, so we need to explicitly check both admin and wearer in this case + _checkAdminOrWearer(_newAdminHat); + } + + // Linkages must be initiated by a request + if (_newAdminHat != linkedTreeRequests[_topHatDomain]) + revert LinkageNotRequested(); + + // remove the request -- ensures all linkages are initialized by unique requests, + // except for relinks (see `relinkTopHatWithinTree`) + delete linkedTreeRequests[_topHatDomain]; + + // execute the link. Replaces existing link, if any. + _linkTopHatToTree( + _topHatDomain, + _newAdminHat, + _eligibility, + _toggle, + _details, + _imageURI + ); + } + /** + * @notice Unlink a Tree from the parent tree + * @dev This can only be called by an admin of the tree root. Fails if the topHat to unlink has no non-zero wearer, which can occur if... + * - It's wearer is in badStanding + * - It has been revoked from its wearer (and possibly burned)˘ + * - It is not active (ie toggled off) + * @param _topHatDomain The 32 bit domain of the topHat to unlink + * @param _wearer The current wearer of the topHat to unlink + */ function unlinkTopHatFromTree( - uint32 _topHatId, + uint32 _topHatDomain, address _wearer - ) external override {} + ) external { + uint256 fullTopHatId = uint256(_topHatDomain) << 224; // (256 - TOPHAT_ADDRESS_SPACE); + _checkAdmin(fullTopHatId); + + // prevent unlinking if the topHat has no non-zero wearer + // since we cannot search the entire address space for a wearer, we require the caller to provide the wearer + if (_wearer == address(0) || !isWearerOfHat(_wearer, fullTopHatId)) + revert InvalidUnlink(); + + // execute the unlink + delete linkedTreeAdmins[_topHatDomain]; + // remove the request — ensures all linkages are initialized by unique requests + delete linkedTreeRequests[_topHatDomain]; + + // reset eligibility and storage to defaults for unlinked top hats + Hat storage hat = _hats[fullTopHatId]; + delete hat.eligibility; + delete hat.toggle; + + emit TopHatLinked(_topHatDomain, 0); + } + /// @notice Move a tree root to a different position within the same parent tree, + /// without a request. Valid destinations include within the same local tree as the origin, + /// or to the local tree of the tippyTopHat. TippyTopHat wearers can bypass this restriction + /// to relink to anywhere in its full tree. + /// @dev Caller must be both an admin tree root and admin or wearer of `_newAdminHat`. + /// @param _topHatDomain The 32 bit domain of the topHat to relink + /// @param _newAdminHat The new admin for the linked tree + /// @param _eligibility Optional new eligibility module for the linked topHat + /// @param _toggle Optional new toggle module for the linked topHat + /// @param _details Optional new details for the linked topHat + /// @param _imageURI Optional new imageURI for the linked topHat function relinkTopHatWithinTree( uint32 _topHatDomain, uint256 _newAdminHat, @@ -934,97 +1418,167 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { address _toggle, string calldata _details, string calldata _imageURI - ) external override {} + ) external { + uint256 fullTopHatId = uint256(_topHatDomain) << 224; // (256 - TOPHAT_ADDRESS_SPACE); - function viewHat( - uint256 _hatId - ) - external - view - override - returns ( - string memory _details, - uint32 _maxSupply, - uint32 _supply, - address _eligibility, - address _toggle, - string memory _imageURI, - uint16 _lastHatId, - bool _mutable, - bool _active - ) - {} + // msg.sender being capable of both requesting and approving allows us to skip the request step + _checkAdmin(fullTopHatId); // "requester" must be admin - function isInGoodStanding( - address _wearer, - uint256 _hatId - ) external view override returns (bool standing) {} + // "approver" can be wearer or admin + if (getHatLevel(_newAdminHat) < MAX_LEVELS) { + _checkAdmin(buildHatId(_newAdminHat, 1)); + } else { + // the above buildHatId trick doesn't work for the last hat level, so we need to explicitly check both admin and wearer in this case + _checkAdminOrWearer(_newAdminHat); + } - function isEligible( - address _wearer, - uint256 _hatId - ) public view returns (bool eligible) { - eligible = _isEligible(_wearer, _hats[_hatId], _hatId); + // execute the new link, replacing the old link + _linkTopHatToTree( + _topHatDomain, + _newAdminHat, + _eligibility, + _toggle, + _details, + _imageURI + ); } - function getHatToggleModule( - uint256 _hatId - ) external view override returns (address toggle) {} - - function getHatMaxSupply( - uint256 _hatId - ) external view override returns (uint32 maxSupply) {} - - function hatSupply( - uint256 _hatId - ) external view override returns (uint32 supply) {} - - function getImageURIForHat( - uint256 _hatId - ) external view override returns (string memory _uri) {} - - function balanceOf( - address _wearer, - uint256 _hatId - ) public view override(ERC1155, IHats) returns (uint256 balance) { - Hat storage hat = _hats[_hatId]; + /// @notice Internal function to link a Tree under a parent Tree, with protection against circular linkages and relinking to a separate Tree, + /// with options to add eligibility or toggle modules and change its metadata + /// @dev Linking `_topHatDomain` replaces any existing links + /// @param _topHatDomain The 32 bit domain of the topHat to link + /// @param _newAdminHat The new admin for the linked tree + /// @param _eligibility Optional new eligibility module for the linked topHat + /// @param _toggle Optional new toggle module for the linked topHat + /// @param _details Optional new details for the linked topHat + /// @param _imageURI Optional new imageURI for the linked topHat + function _linkTopHatToTree( + uint32 _topHatDomain, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) internal { + if (!noCircularLinkage(_topHatDomain, _newAdminHat)) + revert CircularLinkage(); + { + uint256 linkedAdmin = linkedTreeAdmins[_topHatDomain]; + + // disallow relinking to separate tree + if (linkedAdmin > 0) { + uint256 tippyTopHat = uint256( + getTippyTopHatDomain(_topHatDomain) + ) << 224; + if (!isWearerOfHat(msg.sender, tippyTopHat)) { + uint256 destLocalTopHat = uint256( + (_newAdminHat >> 224) << 224 + ); // (256 - TOPHAT_ADDRESS_SPACE); + // for non-tippyTopHat wearers: destination local tophat must be either... + // a) the same as origin local tophat, or + // b) within the tippy top hat's local tree + uint256 originLocalTopHat = (linkedAdmin >> 224) << 224; // (256 - TOPHAT_ADDRESS_SPACE); + if ( + destLocalTopHat != originLocalTopHat && + destLocalTopHat != tippyTopHat + ) { + revert CrossTreeLinkage(); + } + // for tippyTopHat weerers: destination must be within the same super tree + } else if ( + !sameTippyTopHatDomain(_topHatDomain, _newAdminHat) + ) { + revert CrossTreeLinkage(); + } + } + } - balance = 0; + // update and log the linked topHat's modules and metadata, if any changes + uint256 topHatId = uint256(_topHatDomain) << 224; + Hat storage hat = _hats[topHatId]; - if (_isActive(hat, _hatId) && _isEligible(_wearer, hat, _hatId)) { - balance = super.balanceOf(_wearer, _hatId); + if (_eligibility != address(0)) { + hat.eligibility = _eligibility; + emit HatEligibilityChanged(topHatId, _eligibility); + } + if (_toggle != address(0)) { + hat.toggle = _toggle; + emit HatToggleChanged(topHatId, _toggle); } - } - - function balanceOfBatch( - address[] calldata _wearers, - uint256[] calldata _hatIds - ) public view override(ERC1155, IHats) returns (uint256[] memory balances) { - if (_wearers.length != _hatIds.length) - revert BatchArrayLengthMismatch(); - balances = new uint256[](_wearers.length); + uint256 length = bytes(_details).length; + if (length > 0) { + if (length > 7000) revert StringTooLong(); + hat.details = _details; + emit HatDetailsChanged(topHatId, _details); + } - // Unchecked because the only math done is incrementing - // the array index counter which cannot possibly overflow. - unchecked { - for (uint256 i; i < _wearers.length; ++i) { - balances[i] = balanceOf(_wearers[i], _hatIds[i]); - } + length = bytes(_imageURI).length; + if (length > 0) { + if (length > 7000) revert StringTooLong(); + hat.imageURI = _imageURI; + emit HatImageURIChanged(topHatId, _imageURI); } + + // store the new linked admin + linkedTreeAdmins[_topHatDomain] = _newAdminHat; + emit TopHatLinked(_topHatDomain, _newAdminHat); } - function uri( - uint256 - ) public pure override(ERC1155, IHats) returns (string memory _uri) { - _uri = ""; + /*////////////////////////////////////////////////////////////// + HATS VIEW FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + /// @notice View the properties of a given Hat + /// @param _hatId The id of the Hat + /// @return details The details of the Hat + /// @return maxSupply The max supply of tokens for this Hat + /// @return supply The number of current wearers of this Hat + /// @return eligibility The eligibility address for this Hat + /// @return toggle The toggle address for this Hat + /// @return imageURI The image URI used for this Hat + /// @return lastHatId The most recently created Hat with this Hat as admin; also the count of Hats with this Hat as admin + /// @return mutable_ Whether this hat's properties can be changed + /// @return active Whether the Hat is current active, as read from `_isActive` + function viewHat( + uint256 _hatId + ) + public + view + returns ( + string memory details, + uint32 maxSupply, + uint32 supply, + address eligibility, + address toggle, + string memory imageURI, + uint16 lastHatId, + bool mutable_, + bool active + ) + { + Hat storage hat = _hats[_hatId]; + details = hat.details; + maxSupply = hat.maxSupply; + supply = hat.supply; + eligibility = hat.eligibility; + toggle = hat.toggle; + imageURI = getImageURIForHat(_hatId); + lastHatId = hat.lastHatId; + mutable_ = _isMutable(hat); + active = _isActive(hat, _hatId); } - /// @notice Checks whether msg.sender is an admin of a hat, and reverts if not - function _checkAdmin(uint256 _hatId) internal view { - if (!isAdminOfHat(msg.sender, _hatId)) { - revert NotAdmin(msg.sender, _hatId); - } + /// @notice Checks whether a given address wears a given Hat + /// @dev Convenience function that wraps `balanceOf` + /// @param _user The address in question + /// @param _hatId The id of the Hat that the `_user` might wear + /// @return isWearer Whether the `_user` wears the Hat. + function isWearerOfHat( + address _user, + uint256 _hatId + ) public view returns (bool isWearer) { + isWearer = (balanceOf(_user, _hatId) > 0); } /// @notice Checks whether a given address serves as the admin of a given Hat @@ -1096,13 +1650,11 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { } } - function isWearerOfHat( - address _user, - uint256 _hatId - ) public view returns (bool isWearer) { - isWearer = (balanceOf(_user, _hatId) > 0); - } - + /// @notice Checks the active status of a hat + /// @dev For internal use instead of `isActive` when passing Hat as param is preferable + /// @param _hat The Hat struct + /// @param _hatId The id of the hat + /// @return active The active status of the hat function _isActive( Hat storage _hat, uint256 _hatId @@ -1136,6 +1688,81 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { } } + /// @notice Checks the active status of a hat + /// @param _hatId The id of the hat + /// @return active Whether the hat is active + function isActive(uint256 _hatId) external view returns (bool active) { + active = _isActive(_hats[_hatId], _hatId); + } + + /// @notice Internal function to retrieve a hat's status from storage + /// @dev reads the 0th bit of the hat's config + /// @param _hat The hat object + /// @return status Whether the hat is active + function _getHatStatus( + Hat storage _hat + ) internal view returns (bool status) { + status = (_hat.config >> 95 != 0); + } + + /// @notice Internal function to retrieve a hat's mutability setting + /// @dev reads the 1st bit of the hat's config + /// @param _hat The hat object + /// @return _mutable Whether the hat is mutable + function _isMutable( + Hat storage _hat + ) internal view returns (bool _mutable) { + _mutable = (_hat.config & uint96(1 << 94) != 0); + } + + /// @notice Checks whether a wearer of a Hat is in good standing + /// @param _wearer The address of the Hat wearer + /// @param _hatId The id of the Hat + /// @return standing Whether the wearer is in good standing + function isInGoodStanding( + address _wearer, + uint256 _hatId + ) public view returns (bool standing) { + (bool success, bytes memory returndata) = _hats[_hatId] + .eligibility + .staticcall( + abi.encodeWithSignature( + "getWearerStatus(address,uint256)", + _wearer, + _hatId + ) + ); + + /* + * if function call succeeds with data of length == 64, then we know the contract exists + * and has the getWearerStatus function (which returns two words). + * But — since function selectors don't include return types — we still can't assume that the return data is two booleans, + * so we treat it as a uint so it will always safely decode without throwing. + */ + if (success && returndata.length == 64) { + // check the returndata manually + (uint256 firstWord, uint256 secondWord) = abi.decode( + returndata, + (uint256, uint256) + ); + // returndata is valid + if (firstWord < 2 && secondWord < 2) { + standing = (secondWord == 1) ? true : false; + // returndata is invalid + } else { + standing = !badStandings[_hatId][_wearer]; + } + } else { + standing = !badStandings[_hatId][_wearer]; + } + } + + /// @notice Internal call to check whether an address is eligible for a given Hat + /// @dev Tries an external call to the Hat's eligibility module, defaulting to existing badStandings state if the call fails (ie if the eligibility module address does not conform to the IHatsEligibility interface) + /// @param _wearer The address of the Hat wearer + /// @param _hat The Hat object + /// @param _hatId The id of the Hat + /// @return eligible Whether the wearer is eligible for the Hat function _isEligible( address _wearer, Hat storage _hat, @@ -1177,9 +1804,242 @@ contract MockHats is IHats, ERC1155, MockHatsIdUtilities { } } - function _getHatStatus( - Hat storage _hat - ) internal view returns (bool status) { - status = (_hat.config >> 95 != 0); + /// @notice Checks whether an address is eligible for a given Hat + /// @dev Public function for use when passing a Hat object is not possible or preferable + /// @param _hatId The id of the Hat + /// @param _wearer The address to check + /// @return eligible Whether the wearer is eligible for the Hat + function isEligible( + address _wearer, + uint256 _hatId + ) public view returns (bool eligible) { + eligible = _isEligible(_wearer, _hats[_hatId], _hatId); + } + + /// @notice Gets the current supply of a Hat + /// @dev Only tracks explicit burns and mints, not dynamic revocations + /// @param _hatId The id of the Hat + /// @return supply The current supply of the Hat + function hatSupply(uint256 _hatId) external view returns (uint32 supply) { + supply = _hats[_hatId].supply; + } + + /// @notice Gets the eligibility module for a hat + /// @param _hatId The hat whose eligibility module we're looking for + /// @return eligibility The eligibility module for this hat + function getHatEligibilityModule( + uint256 _hatId + ) external view returns (address eligibility) { + eligibility = _hats[_hatId].eligibility; + } + + /// @notice Gets the toggle module for a hat + /// @param _hatId The hat whose toggle module we're looking for + /// @return toggle The toggle module for this hat + function getHatToggleModule( + uint256 _hatId + ) external view returns (address toggle) { + toggle = _hats[_hatId].toggle; + } + + /// @notice Gets the max supply for a hat + /// @param _hatId The hat whose max supply we're looking for + /// @return maxSupply The maximum possible quantity of this hat that could be minted + function getHatMaxSupply( + uint256 _hatId + ) external view returns (uint32 maxSupply) { + maxSupply = _hats[_hatId].maxSupply; + } + + /// @notice Gets the imageURI for a given hat + /// @dev If this hat does not have an imageURI set, recursively get the imageURI from + /// its admin + /// @param _hatId The hat whose imageURI we're looking for + /// @return _uri The imageURI of this hat or, if empty, its admin + function getImageURIForHat( + uint256 _hatId + ) public view returns (string memory _uri) { + // check _hatId first to potentially avoid the `getHatLevel` call + Hat storage hat = _hats[_hatId]; + + string memory imageURI = hat.imageURI; // save 1 SLOAD + + // if _hatId has an imageURI, we return it + if (bytes(imageURI).length > 0) { + return imageURI; + } + + // otherwise, we check its branch of admins + uint256 level = getHatLevel(_hatId); + + // but first we check if _hatId is a tophat, in which case we fall back to the global image uri + if (level == 0) return baseImageURI; + + // otherwise, we check each of its admins for a valid imageURI + uint256 id; + + // already checked at `level` above, so we start the loop at `level - 1` + for (uint256 i = level - 1; i > 0; ) { + id = getAdminAtLevel(_hatId, uint32(i)); + hat = _hats[id]; + imageURI = hat.imageURI; + + if (bytes(imageURI).length > 0) { + return imageURI; + } + // should not underflow given stopping condition is > 0 + unchecked { + --i; + } + } + + id = getAdminAtLevel(_hatId, 0); + hat = _hats[id]; + imageURI = hat.imageURI; + + if (bytes(imageURI).length > 0) { + return imageURI; + } + + // if none of _hatId's admins has an imageURI of its own, we again fall back to the global image uri + _uri = baseImageURI; + } + + /// @notice Constructs the URI for a Hat, using data from the Hat struct + /// @return _uri An ERC1155-compatible JSON string + function _constructURI(uint256) internal pure returns (string memory _uri) { + _uri = ""; + } + + /*////////////////////////////////////////////////////////////// + ERC1155 OVERRIDES + //////////////////////////////////////////////////////////////*/ + + /// @notice Gets the Hat token balance of a user for a given Hat + /// @dev Balance is dynamic based on the hat's status and wearer's eligibility, so off-chain balance data indexed from events may not be in sync + /// @param _wearer The address whose balance is being checked + /// @param _hatId The id of the Hat + /// @return balance The `wearer`'s balance of the Hat tokens. Can never be > 1. + function balanceOf( + address _wearer, + uint256 _hatId + ) public view override(ERC1155, IHats) returns (uint256 balance) { + Hat storage hat = _hats[_hatId]; + + balance = 0; + + if (_isActive(hat, _hatId) && _isEligible(_wearer, hat, _hatId)) { + balance = super.balanceOf(_wearer, _hatId); + } + } + + /// @notice Internal call to mint a Hat token to a wearer + /// @dev Unsafe if called when `_wearer` has a non-zero balance of `_hatId` + /// @param _wearer The wearer of the Hat and the recipient of the newly minted token + /// @param _hatId The id of the Hat to mint + function _mintHat(address _wearer, uint256 _hatId) internal { + unchecked { + // should not overflow since `mintHat` enforces max balance of 1 + _balanceOf[_wearer][_hatId] = 1; + + // increment Hat supply counter + // should not overflow given AllHatsWorn check in `mintHat` + ++_hats[_hatId].supply; + } + + emit TransferSingle(msg.sender, address(0), _wearer, _hatId, 1); + } + + /// @notice Internal call to burn a wearer's Hat token + /// @dev Unsafe if called when `_wearer` doesn't have a zero balance of `_hatId` + /// @param _wearer The wearer from which to burn the Hat token + /// @param _hatId The id of the Hat to burn + function _burnHat(address _wearer, uint256 _hatId) internal { + // neither should underflow since `_burnHat` is never called on non-positive balance + unchecked { + _balanceOf[_wearer][_hatId] = 0; + + // decrement Hat supply counter + --_hats[_hatId].supply; + } + + emit TransferSingle(msg.sender, _wearer, address(0), _hatId, 1); + } + + /// @notice Approvals are not necessary for Hats since transfers are not handled by the wearer + /// @dev Admins should use `transferHat()` to transfer + function setApprovalForAll(address, bool) public pure override { + revert(); + } + + /// @notice Safe transfers are not necessary for Hats since transfers are not handled by the wearer + /// @dev Admins should use `transferHat()` to transfer + function safeTransferFrom( + address, + address, + uint256, + uint256, + bytes calldata + ) public pure override { + revert(); + } + + /// @notice Safe transfers are not necessary for Hats since transfers are not handled by the wearer + function safeBatchTransferFrom( + address, + address, + uint256[] calldata, + uint256[] calldata, + bytes calldata + ) public pure override { + revert(); + } + + /** + * @notice ERC165 interface detection + * @dev While Hats Protocol conforms to the ERC1155 *interface*, it does not fully conform to the ERC1155 *specification* + * since it does not implement the ERC1155Receiver functionality. + * For this reason, this function overrides the ERC1155 implementation to return false for ERC1155. + * @param interfaceId The interface identifier, as specified in ERC-165 + * @return bool True if the contract implements `interfaceId` and false otherwise + */ + function supportsInterface( + bytes4 interfaceId + ) public pure override returns (bool) { + return + interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 + // interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 + interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI + } + + /// @notice Batch retrieval for wearer balances + /// @dev Given the higher gas overhead of Hats balanceOf checks, large batches may be high cost or run into gas limits + /// @param _wearers Array of addresses to check balances for + /// @param _hatIds Array of Hat ids to check, using the same index as _wearers + function balanceOfBatch( + address[] calldata _wearers, + uint256[] calldata _hatIds + ) public view override(ERC1155, IHats) returns (uint256[] memory balances) { + if (_wearers.length != _hatIds.length) + revert BatchArrayLengthMismatch(); + + balances = new uint256[](_wearers.length); + + // Unchecked because the only math done is incrementing + // the array index counter which cannot possibly overflow. + unchecked { + for (uint256 i; i < _wearers.length; ++i) { + balances[i] = balanceOf(_wearers[i], _hatIds[i]); + } + } + } + + /// @notice View the uri for a Hat + /// @param id The id of the Hat + /// @return _uri An 1155-compatible JSON object + function uri( + uint256 id + ) public pure override(ERC1155, IHats) returns (string memory _uri) { + _uri = _constructURI(id); } } From 5910fa48da7f8ab2da5d6b77a09f25e430d1d17c Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 10:40:48 -0400 Subject: [PATCH 175/206] DecentHatsUtils contract should be abstract, it can only be inherited --- contracts/DecentHatsUtils.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/DecentHatsUtils.sol b/contracts/DecentHatsUtils.sol index 84367641..b9382aef 100644 --- a/contracts/DecentHatsUtils.sol +++ b/contracts/DecentHatsUtils.sol @@ -10,7 +10,7 @@ import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.so import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; -contract DecentHatsUtils { +abstract contract DecentHatsUtils { bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; From 1fd29303433e7521edf8761d0d4316df9fc7f4e1 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 11:48:20 -0400 Subject: [PATCH 176/206] Rename "registry" to "erc6551Registry" --- contracts/DecentHatsCreationModule.sol | 16 ++++++++-------- contracts/DecentHatsUtils.sol | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index 27fb22d1..cdbee06e 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -64,12 +64,12 @@ contract DecentHatsCreationModule is DecentHatsUtils { function createAndDeclareTree(CreateTreeParams calldata params) external { IHats hatsProtocol = params.hatsProtocol; address hatsAccountImplementation = params.hatsAccountImplementation; - IERC6551Registry registry = params.erc6551Registry; + IERC6551Registry erc6551Registry = params.erc6551Registry; // Create Top Hat (uint256 topHatId, address topHatAccount) = _processTopHat( hatsProtocol, - registry, + erc6551Registry, hatsAccountImplementation, params.keyValuePairs, params.topHat @@ -78,7 +78,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { // Create Admin Hat uint256 adminHatId = _processAdminHat( hatsProtocol, - registry, + erc6551Registry, hatsAccountImplementation, topHatId, topHatAccount, @@ -91,7 +91,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { HatParams memory hat = params.hats[i]; _processHat( hatsProtocol, - registry, + erc6551Registry, hatsAccountImplementation, topHatId, topHatAccount, @@ -113,7 +113,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { function _processTopHat( IHats hatsProtocol, - IERC6551Registry registry, + IERC6551Registry erc6551Registry, address hatsAccountImplementation, address keyValuePairs, TopHatParams memory topHat @@ -139,7 +139,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { ); // Create top hat account - topHatAccount = registry.createAccount( + topHatAccount = erc6551Registry.createAccount( hatsAccountImplementation, SALT, block.chainid, @@ -166,7 +166,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { function _processAdminHat( IHats hatsProtocol, - IERC6551Registry registry, + IERC6551Registry erc6551Registry, address hatsAccountImplementation, uint256 topHatId, address topHatAccount, @@ -193,7 +193,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { ); // Create Admin Hat's ERC6551 Account - registry.createAccount( + erc6551Registry.createAccount( hatsAccountImplementation, SALT, block.chainid, diff --git a/contracts/DecentHatsUtils.sol b/contracts/DecentHatsUtils.sol index b9382aef..d9972e19 100644 --- a/contracts/DecentHatsUtils.sol +++ b/contracts/DecentHatsUtils.sol @@ -37,7 +37,7 @@ abstract contract DecentHatsUtils { function _processHat( IHats hatsProtocol, - IERC6551Registry registry, + IERC6551Registry erc6551Registry, address hatsAccountImplementation, uint256 topHatId, address topHatAccount, @@ -68,7 +68,7 @@ abstract contract DecentHatsUtils { // Get the stream recipient (based on termed or not) address streamRecipient = _setupStreamRecipient( - registry, + erc6551Registry, hatsAccountImplementation, address(hatsProtocol), hat.termEndDateTs, @@ -158,7 +158,7 @@ abstract contract DecentHatsUtils { // Exists to avoid stack too deep errors function _setupStreamRecipient( - IERC6551Registry registry, + IERC6551Registry erc6551Registry, address hatsAccountImplementation, address hatsProtocol, uint128 termEndDateTs, @@ -172,7 +172,7 @@ abstract contract DecentHatsUtils { // Otherwise, the Hat's smart account is the stream recipient return - registry.createAccount( + erc6551Registry.createAccount( hatsAccountImplementation, SALT, block.chainid, From 595f12b89f907e50a30884344c3b622fea1013dc Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 11:48:52 -0400 Subject: [PATCH 177/206] Create tests for DecntHatsUtils contract --- contracts/mocks/MockDecentHatsUtils.sol | 34 +++ test/DecentHatsUtils.test.ts | 305 ++++++++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 contracts/mocks/MockDecentHatsUtils.sol create mode 100644 test/DecentHatsUtils.test.ts diff --git a/contracts/mocks/MockDecentHatsUtils.sol b/contracts/mocks/MockDecentHatsUtils.sol new file mode 100644 index 00000000..36d3ea0e --- /dev/null +++ b/contracts/mocks/MockDecentHatsUtils.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +import {DecentHatsUtils} from "../DecentHatsUtils.sol"; +import {IHats} from "../interfaces/hats/full/IHats.sol"; +import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/full/IHatsModuleFactory.sol"; + +contract MockDecentHatsUtils is DecentHatsUtils { + // Expose the internal _processHat function for testing + function processHat( + IHats hatsProtocol, + IERC6551Registry erc6551Registry, + address hatsAccountImplementation, + uint256 topHatId, + address topHatAccount, + IHatsModuleFactory hatsModuleFactory, + address hatsElectionsEligibilityImplementation, + uint256 adminHatId, + HatParams memory hat + ) external { + _processHat( + hatsProtocol, + erc6551Registry, + hatsAccountImplementation, + topHatId, + topHatAccount, + hatsModuleFactory, + hatsElectionsEligibilityImplementation, + adminHatId, + hat + ); + } +} diff --git a/test/DecentHatsUtils.test.ts b/test/DecentHatsUtils.test.ts new file mode 100644 index 00000000..e223d15e --- /dev/null +++ b/test/DecentHatsUtils.test.ts @@ -0,0 +1,305 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +import hre from 'hardhat'; + +import { + MockDecentHatsUtils, + MockDecentHatsUtils__factory, + MockHats, + MockHats__factory, + ERC6551Registry, + ERC6551Registry__factory, + MockHatsAccount, + MockHatsAccount__factory, + MockHatsModuleFactory, + MockHatsModuleFactory__factory, + MockSablierV2LockupLinear, + MockSablierV2LockupLinear__factory, + MockERC20, + MockERC20__factory, + GnosisSafeL2, + GnosisSafeL2__factory, +} from '../typechain-types'; + +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; + +import { + getHatAccount, + topHatIdToHatId, + predictGnosisSafeAddress, + executeSafeTransaction, +} from './helpers'; + +describe('DecentHatsUtils', () => { + let deployer: SignerWithAddress; + let safeSigner: SignerWithAddress; + let wearer: SignerWithAddress; + + let mockHats: MockHats; + let mockDecentHatsUtils: MockDecentHatsUtils; + let erc6551Registry: ERC6551Registry; + let mockHatsAccount: MockHatsAccount; + let mockHatsModuleFactory: MockHatsModuleFactory; + let mockSablier: MockSablierV2LockupLinear; + let mockERC20: MockERC20; + let gnosisSafe: GnosisSafeL2; + let gnosisSafeAddress: string; + + let topHatId: bigint; + let topHatAccount: string; + let adminHatId: bigint; + let mockHatsElectionsEligibilityImplementationAddress: string; + + beforeEach(async () => { + const signers = await hre.ethers.getSigners(); + [deployer, safeSigner, wearer] = signers; + + // Deploy mock contracts + mockHats = await new MockHats__factory(deployer).deploy(); + mockDecentHatsUtils = await new MockDecentHatsUtils__factory(deployer).deploy(); + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); + mockHatsAccount = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); + + // Deploy Safe + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'setup', + [ + [safeSigner.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ], + ); + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); + + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( + createGnosisSetupCalldata, + saltNum, + gnosisSafeL2SingletonAddress, + gnosisSafeProxyFactory, + ); + gnosisSafeAddress = predictedGnosisSafeAddress; + + await gnosisSafeProxyFactory.createProxyWithNonce( + gnosisSafeL2SingletonAddress, + createGnosisSetupCalldata, + saltNum, + ); + + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); + + // Create top hat and admin hat + await executeSafeTransaction({ + safe: gnosisSafe, + to: await mockHats.getAddress(), + transactionData: MockHats__factory.createInterface().encodeFunctionData('mintTopHat', [ + gnosisSafeAddress, + '', + '', + ]), + signers: [safeSigner], + }); + + topHatId = topHatIdToHatId(await mockHats.lastTopHatId()); + adminHatId = await mockHats.getNextId(topHatId); + + topHatAccount = await ( + await getHatAccount( + topHatId, + erc6551Registry, + await mockHatsAccount.getAddress(), + await mockHats.getAddress(), + ) + ).getAddress(); + + // Create admin hat + await executeSafeTransaction({ + safe: gnosisSafe, + to: await mockHats.getAddress(), + transactionData: MockHats__factory.createInterface().encodeFunctionData('createHat', [ + topHatId, + '', + 1, + await mockHats.getAddress(), + await mockHats.getAddress(), + false, + '', + ]), + signers: [safeSigner], + }); + + // Deploy mock eligibility implementation + const MockHatsElectionsEligibility = await hre.ethers.getContractFactory( + 'MockHatsElectionsEligibility', + ); + const mockHatsElectionsEligibility = await MockHatsElectionsEligibility.deploy(); + mockHatsElectionsEligibilityImplementationAddress = + await mockHatsElectionsEligibility.getAddress(); + + // Mint tokens to mockDecentHatsUtils for Sablier streams + await mockERC20.mint(await gnosisSafe.getAddress(), hre.ethers.parseEther('1000000')); + + await executeSafeTransaction({ + safe: gnosisSafe, + to: gnosisSafeAddress, + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData('enableModule', [ + await mockDecentHatsUtils.getAddress(), + ]), + signers: [safeSigner], + }); + }); + + describe('processHat', () => { + it('Creates an untermed hat with no streams', async () => { + const hatParams = { + wearer: wearer.address, + details: '', + imageURI: '', + sablierStreamsParams: [], + termEndDateTs: 0n, + maxSupply: 1, + isMutable: false, + }; + + const roleHatId = await mockHats.getNextId(adminHatId); + await executeSafeTransaction({ + safe: gnosisSafe, + to: await mockDecentHatsUtils.getAddress(), + transactionData: MockDecentHatsUtils__factory.createInterface().encodeFunctionData( + 'processHat', + [ + await mockHats.getAddress(), + await erc6551Registry.getAddress(), + await mockHatsAccount.getAddress(), + topHatId, + topHatAccount, + await mockHatsModuleFactory.getAddress(), + mockHatsElectionsEligibilityImplementationAddress, + adminHatId, + hatParams, + ], + ), + signers: [safeSigner], + }); + const hatAccount = await getHatAccount( + roleHatId, + erc6551Registry, + await mockHatsAccount.getAddress(), + await mockHats.getAddress(), + ); + expect(await hatAccount.tokenId()).to.equal(roleHatId); + expect(await hatAccount.tokenImplementation()).to.equal(await mockHats.getAddress()); + }); + + it('Creates a termed hat with no streams', async () => { + const termEndDateTs = BigInt(Math.floor(Date.now() / 1000) + 100000); + const hatParams = { + wearer: wearer.address, + details: '', + imageURI: '', + sablierStreamsParams: [], + termEndDateTs, + maxSupply: 1, + isMutable: false, + }; + + const roleHatId = await mockHats.getNextId(adminHatId); + await executeSafeTransaction({ + safe: gnosisSafe, + to: await mockDecentHatsUtils.getAddress(), + transactionData: MockDecentHatsUtils__factory.createInterface().encodeFunctionData( + 'processHat', + [ + await mockHats.getAddress(), + await erc6551Registry.getAddress(), + await mockHatsAccount.getAddress(), + topHatId, + topHatAccount, + await mockHatsModuleFactory.getAddress(), + mockHatsElectionsEligibilityImplementationAddress, + adminHatId, + hatParams, + ], + ), + signers: [safeSigner], + }); + + expect(await mockHats.isWearerOfHat.staticCall(wearer.address, roleHatId)).to.equal(true); + expect(await mockHats.getHatEligibilityModule(roleHatId)).to.not.equal( + hre.ethers.ZeroAddress, + ); + }); + + it('Creates an untermed hat with a stream', async () => { + const currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + const hatParams = { + wearer: wearer.address, + details: '', + imageURI: '', + sablierStreamsParams: [ + { + sablier: await mockSablier.getAddress(), + sender: await mockDecentHatsUtils.getAddress(), + asset: await mockERC20.getAddress(), + timestamps: { + start: currentBlockTimestamp, + cliff: 0, + end: currentBlockTimestamp + 2592000, // 30 days + }, + broker: { account: hre.ethers.ZeroAddress, fee: 0 }, + totalAmount: hre.ethers.parseEther('100'), + cancelable: true, + transferable: false, + }, + ], + termEndDateTs: 0n, + maxSupply: 1, + isMutable: false, + }; + + await executeSafeTransaction({ + safe: gnosisSafe, + to: await mockDecentHatsUtils.getAddress(), + transactionData: MockDecentHatsUtils__factory.createInterface().encodeFunctionData( + 'processHat', + [ + await mockHats.getAddress(), + await erc6551Registry.getAddress(), + await mockHatsAccount.getAddress(), + topHatId, + topHatAccount, + await mockHatsModuleFactory.getAddress(), + mockHatsElectionsEligibilityImplementationAddress, + adminHatId, + hatParams, + ], + ), + signers: [safeSigner], + }); + + const streamCreatedEvents = await mockSablier.queryFilter( + mockSablier.filters.StreamCreated(), + ); + expect(streamCreatedEvents.length).to.equal(1); + + const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); + expect(stream1.startTime).to.equal(currentBlockTimestamp); + expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); + + const event = streamCreatedEvents[0]; + expect(event.args.sender).to.equal(await mockDecentHatsUtils.getAddress()); + expect(event.args.totalAmount).to.equal(hre.ethers.parseEther('100')); + }); + }); +}); From b771ee71f619bfe8e7a43cca2016be593ca50d7b Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 12:09:27 -0400 Subject: [PATCH 178/206] Add comment to contract --- contracts/DecentHatsCreationModule.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index cdbee06e..c60720a7 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -87,6 +87,7 @@ contract DecentHatsCreationModule is DecentHatsUtils { params.adminHat ); + // Create Role Hats for (uint256 i = 0; i < params.hats.length; ) { HatParams memory hat = params.hats[i]; _processHat( From 18d6bfd9b7e7dd909286283f0979a2bde35ad2f0 Mon Sep 17 00:00:00 2001 From: Kellar Date: Thu, 31 Oct 2024 17:24:37 +0000 Subject: [PATCH 179/206] Add tests for DecentHatsModificationModule --- contracts/DecentHatsModificationModule.sol | 2 +- test/DecentHatsModificationModule.test.ts | 421 +++++++++++++++++++++ 2 files changed, 422 insertions(+), 1 deletion(-) create mode 100644 test/DecentHatsModificationModule.test.ts diff --git a/contracts/DecentHatsModificationModule.sol b/contracts/DecentHatsModificationModule.sol index c0affb7f..c01e8d31 100644 --- a/contracts/DecentHatsModificationModule.sol +++ b/contracts/DecentHatsModificationModule.sol @@ -34,7 +34,7 @@ contract DecentHatsModificationModule is DecentHatsUtils { * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. * See: https://github.com/decentdao/decent-interface/issues/2402 */ - function createTestFobarrNewRoleHat( + function createRoleHat( CreateTermedOrUntermedRoleHatParams calldata params ) external { _processHat( diff --git a/test/DecentHatsModificationModule.test.ts b/test/DecentHatsModificationModule.test.ts new file mode 100644 index 00000000..2fc3c861 --- /dev/null +++ b/test/DecentHatsModificationModule.test.ts @@ -0,0 +1,421 @@ +import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; +import { expect } from 'chai'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import { ethers } from 'ethers'; +import hre from 'hardhat'; +import { + GnosisSafeL2, + GnosisSafeL2__factory, + DecentHatsModificationModule__factory, + DecentHatsCreationModule__factory, + KeyValuePairs, + KeyValuePairs__factory, + MockHats__factory, + ERC6551Registry__factory, + MockHatsAccount__factory, + ERC6551Registry, + DecentHatsModificationModule, + MockHatsAccount, + MockHats, + MockSablierV2LockupLinear__factory, + MockSablierV2LockupLinear, + MockERC20__factory, + MockERC20, + ModuleProxyFactory, + DecentAutonomousAdmin, + ModuleProxyFactory__factory, + DecentAutonomousAdmin__factory, + MockHatsModuleFactory__factory, + MockHatsElectionsEligibility__factory, + DecentHatsCreationModule, +} from '../typechain-types'; + +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; +import { + executeSafeTransaction, + getHatAccount, + predictGnosisSafeAddress, + topHatIdToHatId, +} from './helpers'; + +describe('DecentHatsModificationModule', () => { + let safe: SignerWithAddress; + + let mockHats: MockHats; + let mockHatsAddress: string; + + let keyValuePairs: KeyValuePairs; + let gnosisSafe: GnosisSafeL2; + + let decentHatsCreationModule: DecentHatsCreationModule; + let decentHatsCreationModuleAddress: string; + + let decentHatsModificationModule: DecentHatsModificationModule; + let decentHatsModificationModuleAddress: string; + + let gnosisSafeAddress: string; + let erc6551Registry: ERC6551Registry; + + let mockHatsAccountImplementation: MockHatsAccount; + let mockHatsAccountImplementationAddress: string; + + let mockSablier: MockSablierV2LockupLinear; + let mockSablierAddress: string; + + let mockERC20: MockERC20; + let mockERC20Address: string; + + let mockHatsElectionsEligibilityImplementationAddress: string; + let mockHatsModuleFactoryAddress: string; + + let moduleProxyFactory: ModuleProxyFactory; + let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; + + beforeEach(async () => { + const signers = await hre.ethers.getSigners(); + const [deployer] = signers; + [, safe] = signers; + + mockHats = await new MockHats__factory(deployer).deploy(); + mockHatsAddress = await mockHats.getAddress(); + keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); + erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); + mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); + mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); + decentHatsCreationModule = await new DecentHatsCreationModule__factory(deployer).deploy(); + decentHatsCreationModuleAddress = await decentHatsCreationModule.getAddress(); + decentHatsModificationModule = await new DecentHatsModificationModule__factory( + deployer, + ).deploy(); + decentHatsModificationModuleAddress = await decentHatsModificationModule.getAddress(); + moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + + const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); + mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); + + const mockHatsElectionsEligibilityImplementation = + await new MockHatsElectionsEligibility__factory(deployer).deploy(); + mockHatsElectionsEligibilityImplementationAddress = + await mockHatsElectionsEligibilityImplementation.getAddress(); + + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); + const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); + const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); + + const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'setup', + [ + [safe.address], + 1, + hre.ethers.ZeroAddress, + hre.ethers.ZeroHash, + hre.ethers.ZeroAddress, + hre.ethers.ZeroAddress, + 0, + hre.ethers.ZeroAddress, + ], + ); + + const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); + + const predictedGnosisSafeAddress = await predictGnosisSafeAddress( + createGnosisSetupCalldata, + saltNum, + gnosisSafeL2SingletonAddress, + gnosisSafeProxyFactory, + ); + gnosisSafeAddress = predictedGnosisSafeAddress; + + await gnosisSafeProxyFactory.createProxyWithNonce( + gnosisSafeL2SingletonAddress, + createGnosisSetupCalldata, + saltNum, + ); + + gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); + + // Deploy MockSablierV2LockupLinear + mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); + mockSablierAddress = await mockSablier.getAddress(); + + mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); + mockERC20Address = await mockERC20.getAddress(); + + await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); + }); + + describe('DecentHatsModificationModule', () => { + let enableDecentHatsModificationModuleTx: ethers.ContractTransactionResponse; + + beforeEach(async () => { + // Create a tree for the Safe + await executeSafeTransaction({ + safe: gnosisSafe, + to: gnosisSafeAddress, + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'enableModule', + [decentHatsCreationModuleAddress], + ), + signers: [safe], + }); + await executeSafeTransaction({ + safe: gnosisSafe, + to: decentHatsCreationModuleAddress, + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( + 'createAndDeclareTree', + [ + { + hatsProtocol: mockHatsAddress, + erc6551Registry: await erc6551Registry.getAddress(), + hatsModuleFactory: mockHatsModuleFactoryAddress, + moduleProxyFactory: await moduleProxyFactory.getAddress(), + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + hatsAccountImplementation: mockHatsAccountImplementationAddress, + keyValuePairs: await keyValuePairs.getAddress(), + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, + topHat: { + details: '', + imageURI: '', + }, + adminHat: { + details: '', + imageURI: '', + isMutable: false, + }, + hats: [], + }, + ], + ), + signers: [safe], + }); + + enableDecentHatsModificationModuleTx = await executeSafeTransaction({ + safe: gnosisSafe, + to: gnosisSafeAddress, + transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( + 'enableModule', + [decentHatsModificationModuleAddress], + ), + signers: [safe], + }); + }); + + describe('Enabled as a module', () => { + it('Emits an ExecutionSuccess event', async () => { + await expect(enableDecentHatsModificationModuleTx).to.emit(gnosisSafe, 'ExecutionSuccess'); + }); + + it('Emits an EnabledModule event', async () => { + await expect(enableDecentHatsModificationModuleTx) + .to.emit(gnosisSafe, 'EnabledModule') + .withArgs(decentHatsModificationModuleAddress); + }); + }); + + describe('Creating a new untermed hat on existing Tree', () => { + let topHatAccount: MockHatsAccount; + let currentBlockTimestamp: number; + let topHatId: bigint; + let adminHatId: bigint; + let createNewHatData: { + safe: GnosisSafeL2; + to: string; + transactionData: string; + signers: SignerWithAddress[]; + }; + + beforeEach(async () => { + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + topHatId = topHatIdToHatId(await mockHats.lastTopHatId()); + adminHatId = await mockHats.getNextId(topHatId); + + topHatAccount = await getHatAccount( + topHatId, + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress, + ); + + createNewHatData = { + safe: gnosisSafe, + to: decentHatsModificationModuleAddress, + transactionData: + DecentHatsModificationModule__factory.createInterface().encodeFunctionData( + 'createRoleHat', + [ + { + hatsProtocol: mockHatsAddress, + registry: await erc6551Registry.getAddress(), + topHatAccount: await topHatAccount.getAddress(), + hatsAccountImplementation: mockHatsAccountImplementationAddress, + adminHatId, + topHatId, + hat: { + wearer: await topHatAccount.getAddress(), // any non-zero address, + details: '', + imageURI: '', + sablierStreamsParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + termEndDateTs: 0, + maxSupply: 1, + isMutable: true, + }, + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, + hatsModuleFactory: mockHatsModuleFactoryAddress, + }, + ], + ), + signers: [safe], + }; + }); + + it('Emits an ExecutionSuccess event', async () => { + await expect(executeSafeTransaction(createNewHatData)).to.emit( + gnosisSafe, + 'ExecutionSuccess', + ); + }); + + it('Emits an ExecutionFromModuleSuccess event', async () => { + await expect(executeSafeTransaction(createNewHatData)) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsModificationModuleAddress); + }); + + it('Actually creates the new hat', async () => { + const nextHatIdBeforeCreatingNewHats = await mockHats.getNextId(adminHatId); + + const tx = await executeSafeTransaction(createNewHatData); + await tx.wait(); + + const nextHatIdAfterCreatingNewHats = await mockHats.getNextId(adminHatId); + expect(nextHatIdAfterCreatingNewHats).to.not.equal(nextHatIdBeforeCreatingNewHats); + }); + }); + + describe('Creating a new termed hat on existing Tree', () => { + let topHatAccount: MockHatsAccount; + let currentBlockTimestamp: number; + let topHatId: bigint; + let adminHatId: bigint; + let newHatId: bigint; + + let createNewHatData: { + safe: GnosisSafeL2; + to: string; + transactionData: string; + signers: SignerWithAddress[]; + }; + + beforeEach(async () => { + currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; + topHatId = topHatIdToHatId(await mockHats.lastTopHatId()); + adminHatId = await mockHats.getNextId(topHatId); + newHatId = await mockHats.getNextId(adminHatId); + + topHatAccount = await getHatAccount( + topHatId, + erc6551Registry, + mockHatsAccountImplementationAddress, + mockHatsAddress, + ); + + createNewHatData = { + safe: gnosisSafe, + to: decentHatsModificationModuleAddress, + transactionData: + DecentHatsModificationModule__factory.createInterface().encodeFunctionData( + 'createRoleHat', + [ + { + hatsProtocol: mockHatsAddress, + registry: await erc6551Registry.getAddress(), + topHatAccount: await topHatAccount.getAddress(), + hatsAccountImplementation: mockHatsAccountImplementationAddress, + adminHatId, + topHatId, + hat: { + wearer: await topHatAccount.getAddress(), // any non-zero address, + details: '', + imageURI: '', + sablierStreamsParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, + }, + ], + termEndDateTs: currentBlockTimestamp + 2592000, // 30 days from now + maxSupply: 1, + isMutable: true, + }, + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, + hatsModuleFactory: mockHatsModuleFactoryAddress, + }, + ], + ), + signers: [safe], + }; + }); + + it('Emits an ExecutionSuccess event', async () => { + await expect(executeSafeTransaction(createNewHatData)).to.emit( + gnosisSafe, + 'ExecutionSuccess', + ); + }); + + it('Emits an ExecutionFromModuleSuccess event', async () => { + await expect(executeSafeTransaction(createNewHatData)) + .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') + .withArgs(decentHatsModificationModuleAddress); + }); + + it('Emits a HatCreated event', async () => { + await expect(executeSafeTransaction(createNewHatData)).to.emit(mockHats, 'HatCreated'); + + const hatCreatedEvents = await mockHats.queryFilter(mockHats.filters.HatCreated(), 0); + expect(hatCreatedEvents.length).to.equal(3); // 1 for the top hat, 1 for the admin hat, 1 for the new hat + + const latestEvent = hatCreatedEvents[hatCreatedEvents.length - 1]; + expect(latestEvent.args.id).to.equal(newHatId); + }); + + it('Actually creates the new hat', async () => { + const nextHatIdBeforeCreatingNewHats = await mockHats.getNextId(adminHatId); + + await executeSafeTransaction(createNewHatData); + + const nextHatIdAfterCreatingNewHats = await mockHats.getNextId(adminHatId); + expect(nextHatIdAfterCreatingNewHats).to.not.equal(nextHatIdBeforeCreatingNewHats); + }); + }); + }); +}); From 5bee24dcd53f9d933a5d5182832961e3b10bf309 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 13:29:49 -0400 Subject: [PATCH 180/206] Just get rid of DecentHats_0_1_0 --- contracts/DecentAutonomousAdmin.sol | 4 +- contracts/DecentHatsCreationModule.sol | 8 +- contracts/DecentHatsUtils.sol | 6 +- contracts/DecentHats_0_1_0.sol | 288 -------- contracts/DecentSablierStreamManagement.sol | 4 +- .../interfaces/IDecentAutonomousAdmin.sol | 2 +- .../interfaces/hats/{full => }/HatsErrors.sol | 0 .../interfaces/hats/{full => }/HatsEvents.sol | 0 contracts/interfaces/hats/IHats.sol | 165 ++++- .../hats/{full => }/IHatsIdUtilities.sol | 0 .../hats/{full => }/IHatsModuleFactory.sol | 0 contracts/interfaces/hats/full/IHats.sol | 205 ------ .../modules/IHatsElectionsEligibility.sol | 0 .../sablier/{full => }/IAdminable.sol | 0 .../sablier/{full => }/IERC4096.sol | 0 .../sablier/{full => }/ISablierV2Lockup.sol | 0 .../sablier/ISablierV2LockupLinear.sol | 111 ++- .../{full => }/ISablierV2NFTDescriptor.sol | 0 contracts/interfaces/sablier/LockupLinear.sol | 28 - .../sablier/{full => }/types/DataTypes.sol | 0 contracts/mocks/MockDecentHatsUtils.sol | 4 +- contracts/mocks/MockHats.sol | 4 +- .../mocks/MockHatsElectionEligibility.sol | 2 +- contracts/mocks/MockHatsModuleFactory.sol | 2 +- contracts/mocks/MockSablierV2LockupLinear.sol | 2 +- ...=> 017_deploy_DecentHatsCreationModule.ts} | 0 deploy/core/017_deploy_DecentHats_0_1_0.ts | 11 - ...ts => 019_deploy_DecentAutonomousAdmin.ts} | 0 .../sepolia/DecentAutonomousAdmin.json | 270 +++++++ .../sepolia/DecentHatsCreationModule.json | 269 +++++++ .../DecentSablierStreamManagement.json | 30 +- .../7c4217108daa894b08d16e65df533416.json | 387 ++++++++++ test/DecentHats_0_1_0.test.ts | 694 ------------------ test/DecentSablierStreamManagement.test.ts | 48 +- 34 files changed, 1267 insertions(+), 1277 deletions(-) delete mode 100644 contracts/DecentHats_0_1_0.sol rename contracts/interfaces/hats/{full => }/HatsErrors.sol (100%) rename contracts/interfaces/hats/{full => }/HatsEvents.sol (100%) rename contracts/interfaces/hats/{full => }/IHatsIdUtilities.sol (100%) rename contracts/interfaces/hats/{full => }/IHatsModuleFactory.sol (100%) delete mode 100644 contracts/interfaces/hats/full/IHats.sol rename contracts/interfaces/hats/{full => }/modules/IHatsElectionsEligibility.sol (100%) rename contracts/interfaces/sablier/{full => }/IAdminable.sol (100%) rename contracts/interfaces/sablier/{full => }/IERC4096.sol (100%) rename contracts/interfaces/sablier/{full => }/ISablierV2Lockup.sol (100%) rename contracts/interfaces/sablier/{full => }/ISablierV2NFTDescriptor.sol (100%) delete mode 100644 contracts/interfaces/sablier/LockupLinear.sol rename contracts/interfaces/sablier/{full => }/types/DataTypes.sol (100%) rename deploy/core/{019_deploy_DecentHats.ts => 017_deploy_DecentHatsCreationModule.ts} (100%) delete mode 100644 deploy/core/017_deploy_DecentHats_0_1_0.ts rename deploy/core/{020_deploy_DecentAutonomousAdmin.ts => 019_deploy_DecentAutonomousAdmin.ts} (100%) create mode 100644 deployments/sepolia/DecentAutonomousAdmin.json create mode 100644 deployments/sepolia/DecentHatsCreationModule.json create mode 100644 deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json delete mode 100644 test/DecentHats_0_1_0.test.ts diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/DecentAutonomousAdmin.sol index feb879b9..b37d1ec2 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/DecentAutonomousAdmin.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IHats} from "./interfaces/hats/full/IHats.sol"; -import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; +import {IHats} from "./interfaces/hats/IHats.sol"; +import {IHatsElectionsEligibility} from "./interfaces/hats/modules/IHatsElectionsEligibility.sol"; import {FactoryFriendly} from "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol"; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import {IDecentAutonomousAdmin} from "./interfaces/IDecentAutonomousAdmin.sol"; diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/DecentHatsCreationModule.sol index c60720a7..78b70e2e 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/DecentHatsCreationModule.sol @@ -6,10 +6,10 @@ import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/full/IHats.sol"; -import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; -import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; -import {IHatsElectionsEligibility} from "./interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; +import {IHats} from "./interfaces/hats/IHats.sol"; +import {LockupLinear, Broker} from "./interfaces/sablier/types/DataTypes.sol"; +import {IHatsModuleFactory} from "./interfaces/hats/IHatsModuleFactory.sol"; +import {IHatsElectionsEligibility} from "./interfaces/hats/modules/IHatsElectionsEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; import {DecentHatsUtils} from "./DecentHatsUtils.sol"; diff --git a/contracts/DecentHatsUtils.sol b/contracts/DecentHatsUtils.sol index d9972e19..2efe4a67 100644 --- a/contracts/DecentHatsUtils.sol +++ b/contracts/DecentHatsUtils.sol @@ -5,9 +5,9 @@ import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/full/IHats.sol"; -import {LockupLinear, Broker} from "./interfaces/sablier/full/types/DataTypes.sol"; -import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; +import {IHats} from "./interfaces/hats/IHats.sol"; +import {LockupLinear, Broker} from "./interfaces/sablier/types/DataTypes.sol"; +import {IHatsModuleFactory} from "./interfaces/hats/IHatsModuleFactory.sol"; import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; abstract contract DecentHatsUtils { diff --git a/contracts/DecentHats_0_1_0.sol b/contracts/DecentHats_0_1_0.sol deleted file mode 100644 index a44756ee..00000000 --- a/contracts/DecentHats_0_1_0.sol +++ /dev/null @@ -1,288 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity =0.8.19; - -import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; -import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/IHats.sol"; -import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; -import {LockupLinear} from "./interfaces/sablier/LockupLinear.sol"; - -contract DecentHats_0_1_0 { - string public constant NAME = "DecentHats_0_1_0"; - - struct SablierStreamParams { - ISablierV2LockupLinear sablier; - address sender; - uint128 totalAmount; - address asset; - bool cancelable; - bool transferable; - LockupLinear.Timestamps timestamps; - LockupLinear.Broker broker; - } - - struct Hat { - uint32 maxSupply; - string details; - string imageURI; - bool isMutable; - address wearer; - SablierStreamParams[] sablierParams; // Optional Sablier stream parameters - } - - struct CreateTreeParams { - IHats hatsProtocol; - address hatsAccountImplementation; - IERC6551Registry registry; - address keyValuePairs; - string topHatDetails; - string topHatImageURI; - Hat adminHat; - Hat[] hats; - } - - function getSalt() public pure returns (bytes32 salt) { - return - 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; - } - - function declareSafeHatTree( - address _keyValuePairs, - uint256 topHatId - ) internal { - string[] memory keys = new string[](1); - string[] memory values = new string[](1); - keys[0] = "topHatId"; - values[0] = Strings.toString(topHatId); - - IAvatar(msg.sender).execTransactionFromModule( - _keyValuePairs, - 0, - abi.encodeWithSignature( - "updateValues(string[],string[])", - keys, - values - ), - Enum.Operation.Call - ); - } - - function createHat( - IHats _hatsProtocol, - uint256 adminHatId, - Hat memory _hat, - address topHatAccount - ) internal returns (uint256) { - return - _hatsProtocol.createHat( - adminHatId, - _hat.details, - _hat.maxSupply, - topHatAccount, - topHatAccount, - _hat.isMutable, - _hat.imageURI - ); - } - - function createAccount( - IERC6551Registry _registry, - address _hatsAccountImplementation, - bytes32 salt, - address protocolAddress, - uint256 hatId - ) internal returns (address) { - return - _registry.createAccount( - _hatsAccountImplementation, - salt, - block.chainid, - protocolAddress, - hatId - ); - } - - function createTopHatAndAccount( - IHats _hatsProtocol, - string memory _topHatDetails, - string memory _topHatImageURI, - IERC6551Registry _registry, - address _hatsAccountImplementation, - bytes32 salt - ) internal returns (uint256 topHatId, address topHatAccount) { - topHatId = _hatsProtocol.mintTopHat( - address(this), - _topHatDetails, - _topHatImageURI - ); - - topHatAccount = createAccount( - _registry, - _hatsAccountImplementation, - salt, - address(_hatsProtocol), - topHatId - ); - } - - function createHatAndAccountAndMintAndStreams( - IHats hatsProtocol, - uint256 adminHatId, - Hat calldata hat, - address topHatAccount, - IERC6551Registry registry, - address hatsAccountImplementation, - bytes32 salt - ) internal returns (uint256 hatId, address accountAddress) { - hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount); - - accountAddress = createAccount( - registry, - hatsAccountImplementation, - salt, - address(hatsProtocol), - hatId - ); - - if (hat.wearer != address(0)) { - hatsProtocol.mintHat(hatId, hat.wearer); - } - - for (uint256 i = 0; i < hat.sablierParams.length; ) { - SablierStreamParams memory sablierParams = hat.sablierParams[i]; - - // Approve tokens for Sablier - IAvatar(msg.sender).execTransactionFromModule( - sablierParams.asset, - 0, - abi.encodeWithSignature( - "approve(address,uint256)", - address(sablierParams.sablier), - sablierParams.totalAmount - ), - Enum.Operation.Call - ); - - LockupLinear.CreateWithTimestamps memory params = LockupLinear - .CreateWithTimestamps({ - sender: sablierParams.sender, - recipient: accountAddress, - totalAmount: sablierParams.totalAmount, - asset: IERC20(sablierParams.asset), - cancelable: sablierParams.cancelable, - transferable: sablierParams.transferable, - timestamps: sablierParams.timestamps, - broker: sablierParams.broker - }); - - // Proxy the Sablier call through IAvatar - IAvatar(msg.sender).execTransactionFromModule( - address(sablierParams.sablier), - 0, - abi.encodeWithSignature( - "createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))", - params - ), - Enum.Operation.Call - ); - - unchecked { - ++i; - } - } - } - - /** - * Creates a new role hat and any streams on it. - * - * This contract should be enabled a module on the Safe for which the role is to be created, and disable after. - * In order for the module to be able to create hats on behalf of the Safe, the Safe must first - * transfer its top hat to this contract. This function transfers the top hat back to the Safe after - * creating the role hat. - * - * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe. - * - * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order - * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. - * See: https://github.com/decentdao/decent-interface/issues/2402 - */ - function createRoleHat( - IHats hatsProtocol, - uint256 adminHatId, - Hat calldata hat, - uint256 topHatId, - address topHatAccount, - IERC6551Registry registry, - address hatsAccountImplementation, - bytes32 salt - ) public returns (uint256 hatId, address accountAddress) { - (hatId, accountAddress) = createHatAndAccountAndMintAndStreams( - hatsProtocol, - adminHatId, - hat, - topHatAccount, - registry, - hatsAccountImplementation, - salt - ); - - hatsProtocol.transferHat(topHatId, address(this), msg.sender); - } - - /** - * For a safe without any roles previously created on it, this function should be called. It sets up the - * top hat and admin hat, as well as any other hats and their streams that are provided. - * - * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after. - * - * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has - * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, - * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. - * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. - */ - function createAndDeclareTree(CreateTreeParams calldata params) public { - bytes32 salt = getSalt(); - - (uint256 topHatId, address topHatAccount) = createTopHatAndAccount( - params.hatsProtocol, - params.topHatDetails, - params.topHatImageURI, - params.registry, - params.hatsAccountImplementation, - salt - ); - - declareSafeHatTree(params.keyValuePairs, topHatId); - - (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams( - params.hatsProtocol, - topHatId, - params.adminHat, - topHatAccount, - params.registry, - params.hatsAccountImplementation, - salt - ); - - for (uint256 i = 0; i < params.hats.length; ) { - createHatAndAccountAndMintAndStreams( - params.hatsProtocol, - adminHatId, - params.hats[i], - topHatAccount, - params.registry, - params.hatsAccountImplementation, - salt - ); - - unchecked { - ++i; - } - } - - params.hatsProtocol.transferHat(topHatId, address(this), msg.sender); - } -} diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/DecentSablierStreamManagement.sol index 380d9b85..688958bb 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/DecentSablierStreamManagement.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {ISablierV2Lockup} from "./interfaces/sablier/full/ISablierV2Lockup.sol"; -import {Lockup} from "./interfaces/sablier/full/types/DataTypes.sol"; +import {ISablierV2Lockup} from "./interfaces/sablier/ISablierV2Lockup.sol"; +import {Lockup} from "./interfaces/sablier/types/DataTypes.sol"; contract DecentSablierStreamManagement { string public constant NAME = "DecentSablierStreamManagement"; diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentAutonomousAdmin.sol index 2591b02e..42656801 100644 --- a/contracts/interfaces/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/IDecentAutonomousAdmin.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IHats} from "./hats/full/IHats.sol"; +import {IHats} from "./hats/IHats.sol"; interface IDecentAutonomousAdmin { error NotCurrentWearer(); diff --git a/contracts/interfaces/hats/full/HatsErrors.sol b/contracts/interfaces/hats/HatsErrors.sol similarity index 100% rename from contracts/interfaces/hats/full/HatsErrors.sol rename to contracts/interfaces/hats/HatsErrors.sol diff --git a/contracts/interfaces/hats/full/HatsEvents.sol b/contracts/interfaces/hats/HatsEvents.sol similarity index 100% rename from contracts/interfaces/hats/full/HatsEvents.sol rename to contracts/interfaces/hats/HatsEvents.sol diff --git a/contracts/interfaces/hats/IHats.sol b/contracts/interfaces/hats/IHats.sol index c460c46d..5d0cc188 100644 --- a/contracts/interfaces/hats/IHats.sol +++ b/contracts/interfaces/hats/IHats.sol @@ -16,7 +16,11 @@ pragma solidity >=0.8.13; -interface IHats { +import "./IHatsIdUtilities.sol"; +import "./HatsErrors.sol"; +import "./HatsEvents.sol"; + +interface IHats is IHatsIdUtilities, HatsErrors, HatsEvents { function mintTopHat( address _target, string memory _details, @@ -33,10 +37,169 @@ interface IHats { string calldata _imageURI ) external returns (uint256 newHatId); + function batchCreateHats( + uint256[] calldata _admins, + string[] calldata _details, + uint32[] calldata _maxSupplies, + address[] memory _eligibilityModules, + address[] memory _toggleModules, + bool[] calldata _mutables, + string[] calldata _imageURIs + ) external returns (bool success); + + function getNextId(uint256 _admin) external view returns (uint256 nextId); + function mintHat( uint256 _hatId, address _wearer ) external returns (bool success); + function batchMintHats( + uint256[] calldata _hatIds, + address[] calldata _wearers + ) external returns (bool success); + + function setHatStatus( + uint256 _hatId, + bool _newStatus + ) external returns (bool toggled); + + function checkHatStatus(uint256 _hatId) external returns (bool toggled); + + function setHatWearerStatus( + uint256 _hatId, + address _wearer, + bool _eligible, + bool _standing + ) external returns (bool updated); + + function checkHatWearerStatus( + uint256 _hatId, + address _wearer + ) external returns (bool updated); + + function renounceHat(uint256 _hatId) external; + function transferHat(uint256 _hatId, address _from, address _to) external; + + /*////////////////////////////////////////////////////////////// + HATS ADMIN FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function makeHatImmutable(uint256 _hatId) external; + + function changeHatDetails( + uint256 _hatId, + string memory _newDetails + ) external; + + function changeHatEligibility( + uint256 _hatId, + address _newEligibility + ) external; + + function changeHatToggle(uint256 _hatId, address _newToggle) external; + + function changeHatImageURI( + uint256 _hatId, + string memory _newImageURI + ) external; + + function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external; + + function requestLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat + ) external; + + function approveLinkTopHatToTree( + uint32 _topHatId, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external; + + function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external; + + function relinkTopHatWithinTree( + uint32 _topHatDomain, + uint256 _newAdminHat, + address _eligibility, + address _toggle, + string calldata _details, + string calldata _imageURI + ) external; + + /*////////////////////////////////////////////////////////////// + VIEW FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function viewHat( + uint256 _hatId + ) + external + view + returns ( + string memory details, + uint32 maxSupply, + uint32 supply, + address eligibility, + address toggle, + string memory imageURI, + uint16 lastHatId, + bool mutable_, + bool active + ); + + function isWearerOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isWearer); + + function isAdminOfHat( + address _user, + uint256 _hatId + ) external view returns (bool isAdmin); + + function isInGoodStanding( + address _wearer, + uint256 _hatId + ) external view returns (bool standing); + + function isEligible( + address _wearer, + uint256 _hatId + ) external view returns (bool eligible); + + function getHatEligibilityModule( + uint256 _hatId + ) external view returns (address eligibility); + + function getHatToggleModule( + uint256 _hatId + ) external view returns (address toggle); + + function getHatMaxSupply( + uint256 _hatId + ) external view returns (uint32 maxSupply); + + function hatSupply(uint256 _hatId) external view returns (uint32 supply); + + function getImageURIForHat( + uint256 _hatId + ) external view returns (string memory _uri); + + function balanceOf( + address wearer, + uint256 hatId + ) external view returns (uint256 balance); + + function balanceOfBatch( + address[] calldata _wearers, + uint256[] calldata _hatIds + ) external view returns (uint256[] memory); + + function uri(uint256 id) external view returns (string memory _uri); } diff --git a/contracts/interfaces/hats/full/IHatsIdUtilities.sol b/contracts/interfaces/hats/IHatsIdUtilities.sol similarity index 100% rename from contracts/interfaces/hats/full/IHatsIdUtilities.sol rename to contracts/interfaces/hats/IHatsIdUtilities.sol diff --git a/contracts/interfaces/hats/full/IHatsModuleFactory.sol b/contracts/interfaces/hats/IHatsModuleFactory.sol similarity index 100% rename from contracts/interfaces/hats/full/IHatsModuleFactory.sol rename to contracts/interfaces/hats/IHatsModuleFactory.sol diff --git a/contracts/interfaces/hats/full/IHats.sol b/contracts/interfaces/hats/full/IHats.sol deleted file mode 100644 index 5d0cc188..00000000 --- a/contracts/interfaces/hats/full/IHats.sol +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -// Copyright (C) 2023 Haberdasher Labs -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -pragma solidity >=0.8.13; - -import "./IHatsIdUtilities.sol"; -import "./HatsErrors.sol"; -import "./HatsEvents.sol"; - -interface IHats is IHatsIdUtilities, HatsErrors, HatsEvents { - function mintTopHat( - address _target, - string memory _details, - string memory _imageURI - ) external returns (uint256 topHatId); - - function createHat( - uint256 _admin, - string calldata _details, - uint32 _maxSupply, - address _eligibility, - address _toggle, - bool _mutable, - string calldata _imageURI - ) external returns (uint256 newHatId); - - function batchCreateHats( - uint256[] calldata _admins, - string[] calldata _details, - uint32[] calldata _maxSupplies, - address[] memory _eligibilityModules, - address[] memory _toggleModules, - bool[] calldata _mutables, - string[] calldata _imageURIs - ) external returns (bool success); - - function getNextId(uint256 _admin) external view returns (uint256 nextId); - - function mintHat( - uint256 _hatId, - address _wearer - ) external returns (bool success); - - function batchMintHats( - uint256[] calldata _hatIds, - address[] calldata _wearers - ) external returns (bool success); - - function setHatStatus( - uint256 _hatId, - bool _newStatus - ) external returns (bool toggled); - - function checkHatStatus(uint256 _hatId) external returns (bool toggled); - - function setHatWearerStatus( - uint256 _hatId, - address _wearer, - bool _eligible, - bool _standing - ) external returns (bool updated); - - function checkHatWearerStatus( - uint256 _hatId, - address _wearer - ) external returns (bool updated); - - function renounceHat(uint256 _hatId) external; - - function transferHat(uint256 _hatId, address _from, address _to) external; - - /*////////////////////////////////////////////////////////////// - HATS ADMIN FUNCTIONS - //////////////////////////////////////////////////////////////*/ - - function makeHatImmutable(uint256 _hatId) external; - - function changeHatDetails( - uint256 _hatId, - string memory _newDetails - ) external; - - function changeHatEligibility( - uint256 _hatId, - address _newEligibility - ) external; - - function changeHatToggle(uint256 _hatId, address _newToggle) external; - - function changeHatImageURI( - uint256 _hatId, - string memory _newImageURI - ) external; - - function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external; - - function requestLinkTopHatToTree( - uint32 _topHatId, - uint256 _newAdminHat - ) external; - - function approveLinkTopHatToTree( - uint32 _topHatId, - uint256 _newAdminHat, - address _eligibility, - address _toggle, - string calldata _details, - string calldata _imageURI - ) external; - - function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external; - - function relinkTopHatWithinTree( - uint32 _topHatDomain, - uint256 _newAdminHat, - address _eligibility, - address _toggle, - string calldata _details, - string calldata _imageURI - ) external; - - /*////////////////////////////////////////////////////////////// - VIEW FUNCTIONS - //////////////////////////////////////////////////////////////*/ - - function viewHat( - uint256 _hatId - ) - external - view - returns ( - string memory details, - uint32 maxSupply, - uint32 supply, - address eligibility, - address toggle, - string memory imageURI, - uint16 lastHatId, - bool mutable_, - bool active - ); - - function isWearerOfHat( - address _user, - uint256 _hatId - ) external view returns (bool isWearer); - - function isAdminOfHat( - address _user, - uint256 _hatId - ) external view returns (bool isAdmin); - - function isInGoodStanding( - address _wearer, - uint256 _hatId - ) external view returns (bool standing); - - function isEligible( - address _wearer, - uint256 _hatId - ) external view returns (bool eligible); - - function getHatEligibilityModule( - uint256 _hatId - ) external view returns (address eligibility); - - function getHatToggleModule( - uint256 _hatId - ) external view returns (address toggle); - - function getHatMaxSupply( - uint256 _hatId - ) external view returns (uint32 maxSupply); - - function hatSupply(uint256 _hatId) external view returns (uint32 supply); - - function getImageURIForHat( - uint256 _hatId - ) external view returns (string memory _uri); - - function balanceOf( - address wearer, - uint256 hatId - ) external view returns (uint256 balance); - - function balanceOfBatch( - address[] calldata _wearers, - uint256[] calldata _hatIds - ) external view returns (uint256[] memory); - - function uri(uint256 id) external view returns (string memory _uri); -} diff --git a/contracts/interfaces/hats/full/modules/IHatsElectionsEligibility.sol b/contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol similarity index 100% rename from contracts/interfaces/hats/full/modules/IHatsElectionsEligibility.sol rename to contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol diff --git a/contracts/interfaces/sablier/full/IAdminable.sol b/contracts/interfaces/sablier/IAdminable.sol similarity index 100% rename from contracts/interfaces/sablier/full/IAdminable.sol rename to contracts/interfaces/sablier/IAdminable.sol diff --git a/contracts/interfaces/sablier/full/IERC4096.sol b/contracts/interfaces/sablier/IERC4096.sol similarity index 100% rename from contracts/interfaces/sablier/full/IERC4096.sol rename to contracts/interfaces/sablier/IERC4096.sol diff --git a/contracts/interfaces/sablier/full/ISablierV2Lockup.sol b/contracts/interfaces/sablier/ISablierV2Lockup.sol similarity index 100% rename from contracts/interfaces/sablier/full/ISablierV2Lockup.sol rename to contracts/interfaces/sablier/ISablierV2Lockup.sol diff --git a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol index 0aa6cac9..ba6e322f 100644 --- a/contracts/interfaces/sablier/ISablierV2LockupLinear.sol +++ b/contracts/interfaces/sablier/ISablierV2LockupLinear.sol @@ -1,10 +1,113 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.8.22; -import {LockupLinear} from "./LockupLinear.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -interface ISablierV2LockupLinear { +import {Lockup, LockupLinear} from "./types/DataTypes.sol"; +import {ISablierV2Lockup} from "./ISablierV2Lockup.sol"; + +/// @title ISablierV2LockupLinear +/// @notice Creates and manages Lockup streams with a linear distribution function. +interface ISablierV2LockupLinear is ISablierV2Lockup { + /*////////////////////////////////////////////////////////////////////////// + EVENTS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Emitted when a stream is created. + /// @param streamId The ID of the newly created stream. + /// @param funder The address which funded the stream. + /// @param sender The address distributing the assets, which will have the ability to cancel the stream. + /// @param recipient The address receiving the assets. + /// @param amounts Struct encapsulating (i) the deposit amount, and (ii) the broker fee amount, both denoted + /// in units of the asset's decimals. + /// @param asset The contract address of the ERC-20 asset to be distributed. + /// @param cancelable Boolean indicating whether the stream will be cancelable or not. + /// @param transferable Boolean indicating whether the stream NFT is transferable or not. + /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as + /// Unix timestamps. + /// @param broker The address of the broker who has helped create the stream, e.g. a front-end website. + event CreateLockupLinearStream( + uint256 streamId, + address funder, + address indexed sender, + address indexed recipient, + Lockup.CreateAmounts amounts, + IERC20 indexed asset, + bool cancelable, + bool transferable, + LockupLinear.Timestamps timestamps, + address broker + ); + + /*////////////////////////////////////////////////////////////////////////// + CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Retrieves the stream's cliff time, which is a Unix timestamp. A value of zero means there + /// is no cliff. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + function getCliffTime( + uint256 streamId + ) external view returns (uint40 cliffTime); + + /// @notice Retrieves the full stream details. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + /// @return stream See the documentation in {DataTypes}. + function getStream( + uint256 streamId + ) external view returns (LockupLinear.StreamLL memory stream); + + /// @notice Retrieves the stream's start, cliff and end timestamps. + /// @dev Reverts if `streamId` references a null stream. + /// @param streamId The stream ID for the query. + /// @return timestamps See the documentation in {DataTypes}. + function getTimestamps( + uint256 streamId + ) external view returns (LockupLinear.Timestamps memory timestamps); + + /*////////////////////////////////////////////////////////////////////////// + NON-CONSTANT FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + /// @notice Creates a stream by setting the start time to `block.timestamp`, and the end time to + /// the sum of `block.timestamp` and `params.durations.total`. The stream is funded by `msg.sender` and is wrapped + /// in an ERC-721 NFT. + /// + /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event. + /// + /// Requirements: + /// - All requirements in {createWithTimestamps} must be met for the calculated parameters. + /// + /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}. + /// @return streamId The ID of the newly created stream. + function createWithDurations( + LockupLinear.CreateWithDurations calldata params + ) external returns (uint256 streamId); + + /// @notice Creates a stream with the provided start time and end time. The stream is funded by `msg.sender` and is + /// wrapped in an ERC-721 NFT. + /// + /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event. + /// + /// Notes: + /// - A cliff time of zero means there is no cliff. + /// - As long as the times are ordered, it is not an error for the start or the cliff time to be in the past. + /// + /// Requirements: + /// - Must not be delegate called. + /// - `params.totalAmount` must be greater than zero. + /// - If set, `params.broker.fee` must not be greater than `MAX_BROKER_FEE`. + /// - `params.timestamps.start` must be greater than zero and less than `params.timestamps.end`. + /// - If set, `params.timestamps.cliff` must be greater than `params.timestamps.start` and less than + /// `params.timestamps.end`. + /// - `params.timestamps.end` must be in the future. + /// - `params.recipient` must not be the zero address. + /// - `msg.sender` must have allowed this contract to spend at least `params.totalAmount` assets. + /// + /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}. + /// @return streamId The ID of the newly created stream. function createWithTimestamps( LockupLinear.CreateWithTimestamps calldata params ) external returns (uint256 streamId); diff --git a/contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol b/contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol similarity index 100% rename from contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol rename to contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol diff --git a/contracts/interfaces/sablier/LockupLinear.sol b/contracts/interfaces/sablier/LockupLinear.sol deleted file mode 100644 index 0225d060..00000000 --- a/contracts/interfaces/sablier/LockupLinear.sol +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -library LockupLinear { - struct CreateWithTimestamps { - address sender; - address recipient; - uint128 totalAmount; - IERC20 asset; - bool cancelable; - bool transferable; - Timestamps timestamps; - Broker broker; - } - - struct Timestamps { - uint40 start; - uint40 cliff; - uint40 end; - } - - struct Broker { - address account; - uint256 fee; - } -} diff --git a/contracts/interfaces/sablier/full/types/DataTypes.sol b/contracts/interfaces/sablier/types/DataTypes.sol similarity index 100% rename from contracts/interfaces/sablier/full/types/DataTypes.sol rename to contracts/interfaces/sablier/types/DataTypes.sol diff --git a/contracts/mocks/MockDecentHatsUtils.sol b/contracts/mocks/MockDecentHatsUtils.sol index 36d3ea0e..7820eee9 100644 --- a/contracts/mocks/MockDecentHatsUtils.sol +++ b/contracts/mocks/MockDecentHatsUtils.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.28; import {DecentHatsUtils} from "../DecentHatsUtils.sol"; -import {IHats} from "../interfaces/hats/full/IHats.sol"; +import {IHats} from "../interfaces/hats/IHats.sol"; import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; -import {IHatsModuleFactory} from "../interfaces/hats/full/IHatsModuleFactory.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; contract MockDecentHatsUtils is DecentHatsUtils { // Expose the internal _processHat function for testing diff --git a/contracts/mocks/MockHats.sol b/contracts/mocks/MockHats.sol index 886b9c72..fb023cca 100644 --- a/contracts/mocks/MockHats.sol +++ b/contracts/mocks/MockHats.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity =0.8.19; -import {IHats} from "../interfaces/hats/full/IHats.sol"; -import {IHatsIdUtilities} from "../interfaces/hats/full/IHatsIdUtilities.sol"; +import {IHats} from "../interfaces/hats/IHats.sol"; +import {IHatsIdUtilities} from "../interfaces/hats/IHatsIdUtilities.sol"; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol) diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionEligibility.sol index 6dec84c8..baea0999 100644 --- a/contracts/mocks/MockHatsElectionEligibility.sol +++ b/contracts/mocks/MockHatsElectionEligibility.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IHatsElectionsEligibility} from "../interfaces/hats/full/modules/IHatsElectionsEligibility.sol"; +import {IHatsElectionsEligibility} from "../interfaces/hats/modules/IHatsElectionsEligibility.sol"; contract MockHatsElectionsEligibility is IHatsElectionsEligibility { function currentTermEnd() external view returns (uint128) {} diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol index 57ae687b..3f12ddba 100644 --- a/contracts/mocks/MockHatsModuleFactory.sol +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IHatsModuleFactory} from "../interfaces/hats/full/IHatsModuleFactory.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; import {MockHatsElectionsEligibility} from "./MockHatsElectionEligibility.sol"; contract MockHatsModuleFactory is IHatsModuleFactory { diff --git a/contracts/mocks/MockSablierV2LockupLinear.sol b/contracts/mocks/MockSablierV2LockupLinear.sol index 9926a994..ffa7bffc 100644 --- a/contracts/mocks/MockSablierV2LockupLinear.sol +++ b/contracts/mocks/MockSablierV2LockupLinear.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity =0.8.19; +pragma solidity >=0.8.22; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; diff --git a/deploy/core/019_deploy_DecentHats.ts b/deploy/core/017_deploy_DecentHatsCreationModule.ts similarity index 100% rename from deploy/core/019_deploy_DecentHats.ts rename to deploy/core/017_deploy_DecentHatsCreationModule.ts diff --git a/deploy/core/017_deploy_DecentHats_0_1_0.ts b/deploy/core/017_deploy_DecentHats_0_1_0.ts deleted file mode 100644 index 7a2def8c..00000000 --- a/deploy/core/017_deploy_DecentHats_0_1_0.ts +++ /dev/null @@ -1,11 +0,0 @@ -// import { HardhatRuntimeEnvironment } from "hardhat/types" -import { DeployFunction } from 'hardhat-deploy/types'; -// import { deployNonUpgradeable } from "../helpers/deployNonUpgradeable"; - -const func: DeployFunction = async (/* hre: HardhatRuntimeEnvironment */) => { - // No longer deploying DecentHats_0_1_0 to any new networks.. - // This contract has been depreciated. - // await deployNonUpgradeable(hre, "DecentHats_0_1_0"); -}; - -export default func; diff --git a/deploy/core/020_deploy_DecentAutonomousAdmin.ts b/deploy/core/019_deploy_DecentAutonomousAdmin.ts similarity index 100% rename from deploy/core/020_deploy_DecentAutonomousAdmin.ts rename to deploy/core/019_deploy_DecentAutonomousAdmin.ts diff --git a/deployments/sepolia/DecentAutonomousAdmin.json b/deployments/sepolia/DecentAutonomousAdmin.json new file mode 100644 index 00000000..93c44806 --- /dev/null +++ b/deployments/sepolia/DecentAutonomousAdmin.json @@ -0,0 +1,270 @@ +{ + "address": "0x80C7973189D32F145Ef683dCe2720F1bc75623aa", + "abi": [ + { + "inputs": [], + "name": "NotCurrentWearer", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "initializeParams", + "type": "bytes" + } + ], + "name": "setUp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "currentWearer", + "type": "address" + }, + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "nominatedWearer", + "type": "address" + } + ], + "internalType": "struct IDecentAutonomousAdmin.TriggerStartArgs", + "name": "args", + "type": "tuple" + } + ], + "name": "triggerStartNextTerm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x2d5d9cac8b4449a55d0cf35d8657039c23c9d065d8195b487e9b7e29d3918763", + "receipt": { + "to": null, + "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", + "contractAddress": "0x80C7973189D32F145Ef683dCe2720F1bc75623aa", + "transactionIndex": 37, + "gasUsed": "498713", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xda8520b03cec2db8b93fb5375ae3c1d358bba7322d3c12eebdd97ff8077b3ed7", + "transactionHash": "0x2d5d9cac8b4449a55d0cf35d8657039c23c9d065d8195b487e9b7e29d3918763", + "logs": [], + "blockNumber": 6984776, + "cumulativeGasUsed": "5842656", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "7c4217108daa894b08d16e65df533416", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NotCurrentWearer\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initializeParams\",\"type\":\"bytes\"}],\"name\":\"setUp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"currentWearer\",\"type\":\"address\"},{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"nominatedWearer\",\"type\":\"address\"}],\"internalType\":\"struct IDecentAutonomousAdmin.TriggerStartArgs\",\"name\":\"args\",\"type\":\"tuple\"}],\"name\":\"triggerStartNextTerm\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentAutonomousAdmin.sol\":\"DecentAutonomousAdmin\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\n\\nabstract contract FactoryFriendly is OwnableUpgradeable {\\n function setUp(bytes memory initializeParams) public virtual;\\n}\\n\",\"keccak256\":\"0x96e61585b7340a901a54eb4c157ce28b630bff3d9d4597dfaac692128ea458c4\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing 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\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\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. Equivalent to `reinitializer(1)`.\\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\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 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 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\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 *\\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"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/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/DecentAutonomousAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {IHatsElectionsEligibility} from \\\"./interfaces/hats/modules/IHatsElectionsEligibility.sol\\\";\\nimport {FactoryFriendly} from \\\"@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol\\\";\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {IDecentAutonomousAdmin} from \\\"./interfaces/IDecentAutonomousAdmin.sol\\\";\\n\\ncontract DecentAutonomousAdmin is\\n IDecentAutonomousAdmin,\\n ERC165,\\n FactoryFriendly\\n{\\n // //////////////////////////////////////////////////////////////\\n // initializer\\n // //////////////////////////////////////////////////////////////\\n function setUp(bytes memory initializeParams) public override initializer {}\\n\\n // //////////////////////////////////////////////////////////////\\n // Public Functions\\n // //////////////////////////////////////////////////////////////\\n function triggerStartNextTerm(TriggerStartArgs calldata args) public {\\n if (\\n args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId) ==\\n false\\n ) revert NotCurrentWearer();\\n\\n IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility(\\n args.hatsProtocol.getHatEligibilityModule(args.hatId)\\n );\\n\\n hatsElectionModule.startNextTerm();\\n\\n // This will burn the hat since wearer is no longer eligible\\n args.hatsProtocol.checkHatWearerStatus(args.hatId, args.currentWearer);\\n // This will mint the hat to the nominated wearer\\n args.hatsProtocol.mintHat(args.hatId, args.nominatedWearer);\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view override returns (bool) {\\n return\\n interfaceId == type(IDecentAutonomousAdmin).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n}\\n\",\"keccak256\":\"0x6a3fbb0d5393cba9f921404603ace27457a7de32493744deb91fa09229664e4c\",\"license\":\"MIT\"},\"contracts/interfaces/IDecentAutonomousAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {IHats} from \\\"./hats/IHats.sol\\\";\\n\\ninterface IDecentAutonomousAdmin {\\n error NotCurrentWearer();\\n struct TriggerStartArgs {\\n address currentWearer;\\n IHats hatsProtocol;\\n uint256 hatId;\\n address nominatedWearer;\\n }\\n\\n function triggerStartNextTerm(TriggerStartArgs calldata args) external;\\n}\\n\",\"keccak256\":\"0x6c0165ad0aaa6c27c42f3ebd72b069b74e6ee0b05e1ac78deb4390e24fb074f4\",\"license\":\"MIT\"},\"contracts/interfaces/hats/HatsErrors.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsErrors {\\n /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats\\n /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree`\\n error NotAdmin(address user, uint256 hatId);\\n\\n /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat\\n error NotHatWearer();\\n\\n /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat\\n error NotAdminOrWearer();\\n\\n /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached\\n error AllHatsWorn(uint256 hatId);\\n\\n /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin\\n error MaxLevelsReached();\\n\\n /// @notice Emitted when an attempted hat id has empty intermediate level(s)\\n error InvalidHatId();\\n\\n /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat\\n error AlreadyWearingHat(address wearer, uint256 hatId);\\n\\n /// @notice Emitted when attempting to mint a non-existant hat\\n error HatDoesNotExist(uint256 hatId);\\n\\n /// @notice Emmitted when attempting to mint or transfer a hat that is not active\\n error HatNotActive();\\n\\n /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer\\n error NotEligible();\\n\\n /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module\\n error NotHatsToggle();\\n\\n /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module\\n error NotHatsEligibility();\\n\\n /// @notice Emitted when array arguments to a batch function have mismatching lengths\\n error BatchArrayLengthMismatch();\\n\\n /// @notice Emitted when attempting to mutate or transfer an immutable hat\\n error Immutable();\\n\\n /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply\\n error NewMaxSupplyTooLow();\\n\\n /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin\\n error CircularLinkage();\\n\\n /// @notice Emitted when attempting to link or relink a tophat to a separate tree\\n error CrossTreeLinkage();\\n\\n /// @notice Emitted when attempting to link a tophat without a request\\n error LinkageNotRequested();\\n\\n /// @notice Emitted when attempting to unlink a tophat that does not have a wearer\\n /// @dev This ensures that unlinking never results in a bricked tophat\\n error InvalidUnlink();\\n\\n /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address\\n error ZeroAddress();\\n\\n /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters)\\n /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI\\n /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()`\\n error StringTooLong();\\n}\\n\",\"keccak256\":\"0x81b0056b7bed86eabc07c0e4a9655c586ddb8e6c128320593669b76efd5a08de\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/HatsEvents.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsEvents {\\n /// @notice Emitted when a new hat is created\\n /// @param id The id for the new hat\\n /// @param details A description of the Hat\\n /// @param maxSupply The total instances of the Hat that can be worn at once\\n /// @param eligibility The address that can report on the Hat wearer's status\\n /// @param toggle The address that can deactivate the Hat\\n /// @param mutable_ Whether the hat's properties are changeable after creation\\n /// @param imageURI The image uri for this hat and the fallback for its\\n event HatCreated(\\n uint256 id,\\n string details,\\n uint32 maxSupply,\\n address eligibility,\\n address toggle,\\n bool mutable_,\\n string imageURI\\n );\\n\\n /// @notice Emitted when a hat wearer's standing is updated\\n /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction\\n /// @param hatId The id of the wearer's hat\\n /// @param wearer The wearer's address\\n /// @param wearerStanding Whether the wearer is in good standing for the hat\\n event WearerStandingChanged(\\n uint256 hatId,\\n address wearer,\\n bool wearerStanding\\n );\\n\\n /// @notice Emitted when a hat's status is updated\\n /// @param hatId The id of the hat\\n /// @param newStatus Whether the hat is active\\n event HatStatusChanged(uint256 hatId, bool newStatus);\\n\\n /// @notice Emitted when a hat's details are updated\\n /// @param hatId The id of the hat\\n /// @param newDetails The updated details\\n event HatDetailsChanged(uint256 hatId, string newDetails);\\n\\n /// @notice Emitted when a hat's eligibility module is updated\\n /// @param hatId The id of the hat\\n /// @param newEligibility The updated eligibiliy module\\n event HatEligibilityChanged(uint256 hatId, address newEligibility);\\n\\n /// @notice Emitted when a hat's toggle module is updated\\n /// @param hatId The id of the hat\\n /// @param newToggle The updated toggle module\\n event HatToggleChanged(uint256 hatId, address newToggle);\\n\\n /// @notice Emitted when a hat's mutability is updated\\n /// @param hatId The id of the hat\\n event HatMutabilityChanged(uint256 hatId);\\n\\n /// @notice Emitted when a hat's maximum supply is updated\\n /// @param hatId The id of the hat\\n /// @param newMaxSupply The updated max supply\\n event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply);\\n\\n /// @notice Emitted when a hat's image URI is updated\\n /// @param hatId The id of the hat\\n /// @param newImageURI The updated image URI\\n event HatImageURIChanged(uint256 hatId, string newImageURI);\\n\\n /// @notice Emitted when a tophat linkage is requested by its admin\\n /// @param domain The domain of the tree tophat to link\\n /// @param newAdmin The tophat's would-be admin in the parent tree\\n event TopHatLinkRequested(uint32 domain, uint256 newAdmin);\\n\\n /// @notice Emitted when a tophat is linked to a another tree\\n /// @param domain The domain of the newly-linked tophat\\n /// @param newAdmin The tophat's new admin in the parent tree\\n event TopHatLinked(uint32 domain, uint256 newAdmin);\\n}\\n\",\"keccak256\":\"0x53413397d15e1636c3cd7bd667656b79bc2886785403b824bcd4ed122667f2c6\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\nimport \\\"./IHatsIdUtilities.sol\\\";\\nimport \\\"./HatsErrors.sol\\\";\\nimport \\\"./HatsEvents.sol\\\";\\n\\ninterface IHats is IHatsIdUtilities, HatsErrors, HatsEvents {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function batchCreateHats(\\n uint256[] calldata _admins,\\n string[] calldata _details,\\n uint32[] calldata _maxSupplies,\\n address[] memory _eligibilityModules,\\n address[] memory _toggleModules,\\n bool[] calldata _mutables,\\n string[] calldata _imageURIs\\n ) external returns (bool success);\\n\\n function getNextId(uint256 _admin) external view returns (uint256 nextId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function batchMintHats(\\n uint256[] calldata _hatIds,\\n address[] calldata _wearers\\n ) external returns (bool success);\\n\\n function setHatStatus(\\n uint256 _hatId,\\n bool _newStatus\\n ) external returns (bool toggled);\\n\\n function checkHatStatus(uint256 _hatId) external returns (bool toggled);\\n\\n function setHatWearerStatus(\\n uint256 _hatId,\\n address _wearer,\\n bool _eligible,\\n bool _standing\\n ) external returns (bool updated);\\n\\n function checkHatWearerStatus(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool updated);\\n\\n function renounceHat(uint256 _hatId) external;\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n HATS ADMIN FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function makeHatImmutable(uint256 _hatId) external;\\n\\n function changeHatDetails(\\n uint256 _hatId,\\n string memory _newDetails\\n ) external;\\n\\n function changeHatEligibility(\\n uint256 _hatId,\\n address _newEligibility\\n ) external;\\n\\n function changeHatToggle(uint256 _hatId, address _newToggle) external;\\n\\n function changeHatImageURI(\\n uint256 _hatId,\\n string memory _newImageURI\\n ) external;\\n\\n function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external;\\n\\n function requestLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat\\n ) external;\\n\\n function approveLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external;\\n\\n function relinkTopHatWithinTree(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n VIEW FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function viewHat(\\n uint256 _hatId\\n )\\n external\\n view\\n returns (\\n string memory details,\\n uint32 maxSupply,\\n uint32 supply,\\n address eligibility,\\n address toggle,\\n string memory imageURI,\\n uint16 lastHatId,\\n bool mutable_,\\n bool active\\n );\\n\\n function isWearerOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isWearer);\\n\\n function isAdminOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isAdmin);\\n\\n function isInGoodStanding(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool standing);\\n\\n function isEligible(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible);\\n\\n function getHatEligibilityModule(\\n uint256 _hatId\\n ) external view returns (address eligibility);\\n\\n function getHatToggleModule(\\n uint256 _hatId\\n ) external view returns (address toggle);\\n\\n function getHatMaxSupply(\\n uint256 _hatId\\n ) external view returns (uint32 maxSupply);\\n\\n function hatSupply(uint256 _hatId) external view returns (uint32 supply);\\n\\n function getImageURIForHat(\\n uint256 _hatId\\n ) external view returns (string memory _uri);\\n\\n function balanceOf(\\n address wearer,\\n uint256 hatId\\n ) external view returns (uint256 balance);\\n\\n function balanceOfBatch(\\n address[] calldata _wearers,\\n uint256[] calldata _hatIds\\n ) external view returns (uint256[] memory);\\n\\n function uri(uint256 id) external view returns (string memory _uri);\\n}\\n\",\"keccak256\":\"0x2867004bddc5148fa1937f25c0403e5d9977583aaf50fdbdb74bd463f64f21c8\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHatsIdUtilities.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHatsIdUtilities {\\n function buildHatId(\\n uint256 _admin,\\n uint16 _newHat\\n ) external pure returns (uint256 id);\\n\\n function getHatLevel(uint256 _hatId) external view returns (uint32 level);\\n\\n function getLocalHatLevel(\\n uint256 _hatId\\n ) external pure returns (uint32 level);\\n\\n function isTopHat(uint256 _hatId) external view returns (bool _topHat);\\n\\n function isLocalTopHat(\\n uint256 _hatId\\n ) external pure returns (bool _localTopHat);\\n\\n function isValidHatId(\\n uint256 _hatId\\n ) external view returns (bool validHatId);\\n\\n function getAdminAtLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external view returns (uint256 admin);\\n\\n function getAdminAtLocalLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external pure returns (uint256 admin);\\n\\n function getTopHatDomain(\\n uint256 _hatId\\n ) external view returns (uint32 domain);\\n\\n function getTippyTopHatDomain(\\n uint32 _topHatDomain\\n ) external view returns (uint32 domain);\\n\\n function noCircularLinkage(\\n uint32 _topHatDomain,\\n uint256 _linkedAdmin\\n ) external view returns (bool notCircular);\\n\\n function sameTippyTopHatDomain(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat\\n ) external view returns (bool sameDomain);\\n}\\n\",\"keccak256\":\"0x007fcc07b20bf84bacad1f9a2ddf4e30e1a8be961e144b7bef8e98a51781aee9\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.13;\\n\\ninterface IHatsElectionsEligibility {\\n event ElectionOpened(uint128 nextTermEnd);\\n event ElectionCompleted(uint128 termEnd, address[] winners);\\n event NewTermStarted(uint128 termEnd);\\n event Recalled(uint128 termEnd, address[] accounts);\\n\\n /// @notice Returns the first second after the current term ends.\\n /// @dev Also serves as the id for the current term.\\n function currentTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the first second after the next term ends.\\n /// @dev Also serves as the id for the next term.\\n function nextTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the election status (open or closed) for a given term end.\\n /// @param termEnd The term end timestamp to query.\\n function electionStatus(\\n uint128 termEnd\\n ) external view returns (bool isElectionOpen);\\n\\n /// @notice Returns whether a candidate was elected in a given term.\\n /// @param termEnd The term end timestamp to query.\\n /// @param candidate The address of the candidate.\\n function electionResults(\\n uint128 termEnd,\\n address candidate\\n ) external view returns (bool elected);\\n\\n /// @notice Returns the BALLOT_BOX_HAT constant.\\n function BALLOT_BOX_HAT() external pure returns (uint256);\\n\\n /// @notice Returns the ADMIN_HAT constant.\\n function ADMIN_HAT() external pure returns (uint256);\\n\\n /**\\n * @notice Submit the results of an election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the election results are being submitted.\\n * @param _winners The addresses of the winners of the election.\\n */\\n function elect(uint128 _termEnd, address[] calldata _winners) external;\\n\\n /**\\n * @notice Submit the results of a recall election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the recall results are being submitted.\\n * @param _recallees The addresses to be recalled.\\n */\\n function recall(uint128 _termEnd, address[] calldata _recallees) external;\\n\\n /**\\n * @notice Set the next term and open the election for it.\\n * @dev Only callable by the wearer(s) of the ADMIN_HAT.\\n * @param _newTermEnd The id of the term that will be opened.\\n */\\n function setNextTerm(uint128 _newTermEnd) external;\\n\\n /**\\n * @notice Start the next term, updating the current term.\\n * @dev Can be called by anyone, but will revert if conditions are not met.\\n */\\n function startNextTerm() external;\\n\\n /**\\n * @notice Determine the eligibility and standing of a wearer for a hat.\\n * @param _wearer The address of the hat wearer.\\n * @param _hatId The ID of the hat.\\n * @return eligible True if the wearer is eligible for the hat.\\n * @return standing True if the wearer is in good standing.\\n */\\n function getWearerStatus(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible, bool standing);\\n}\\n\",\"keccak256\":\"0x74dfc5d538d866ddb8ee2ca1b569abf62e02d848c59f308adf6075ecff175c7d\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b5061080f8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806301ffc9a7146100675780630ac4a8e81461008f578063715018a6146100a45780638da5cb5b146100ac578063a4f9edbf146100c7578063f2fde38b146100da575b600080fd5b61007a61007536600461064d565b6100ed565b60405190151581526020015b60405180910390f35b6100a261009d36600461067e565b610124565b005b6100a2610405565b6033546040516001600160a01b039091168152602001610086565b6100a26100d53660046106af565b610419565b6100a26100e836600461077d565b610528565b60006001600160e01b03198216630158951d60e31b148061011e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610134604082016020830161077d565b6001600160a01b0316634352409a61014f602084018461077d565b604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301528401356024820152604401602060405180830381865afa15801561019c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c0919061079a565b15156000036101e2576040516302aa5ad560e11b815260040160405180910390fd5b60006101f4604083016020840161077d565b6001600160a01b0316638c07607783604001356040518263ffffffff1660e01b815260040161022591815260200190565b602060405180830381865afa158015610242573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026691906107bc565b9050806001600160a01b0316637dcc80546040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102a357600080fd5b505af11580156102b7573d6000803e3d6000fd5b506102cc92505050604083016020840161077d565b6001600160a01b0316633fa9d54460408401356102ec602086018661077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035c919061079a565b5061036d604083016020840161077d565b6001600160a01b031663641f776e6040840135610390608086016060870161077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156103dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610400919061079a565b505050565b61040d6105a1565b61041760006105fb565b565b600054610100900460ff16158080156104395750600054600160ff909116105b806104535750303b158015610453575060005460ff166001145b6104bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156104de576000805461ff0019166101001790555b8015610524576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6105306105a1565b6001600160a01b0381166105955760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104b2565b61059e816105fb565b50565b6033546001600160a01b031633146104175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104b2565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561065f57600080fd5b81356001600160e01b03198116811461067757600080fd5b9392505050565b6000608082840312801561069157600080fd5b509092915050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156106c157600080fd5b813567ffffffffffffffff8111156106d857600080fd5b8201601f810184136106e957600080fd5b803567ffffffffffffffff81111561070357610703610699565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561073257610732610699565b60405281815282820160200186101561074a57600080fd5b81602084016020830137600091810160200191909152949350505050565b6001600160a01b038116811461059e57600080fd5b60006020828403121561078f57600080fd5b813561067781610768565b6000602082840312156107ac57600080fd5b8151801515811461067757600080fd5b6000602082840312156107ce57600080fd5b81516106778161076856fea26469706673582212203efa05c08e63f84221d377b68763b018336f724f765ab2f48bdef7fc96aa814b64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c806301ffc9a7146100675780630ac4a8e81461008f578063715018a6146100a45780638da5cb5b146100ac578063a4f9edbf146100c7578063f2fde38b146100da575b600080fd5b61007a61007536600461064d565b6100ed565b60405190151581526020015b60405180910390f35b6100a261009d36600461067e565b610124565b005b6100a2610405565b6033546040516001600160a01b039091168152602001610086565b6100a26100d53660046106af565b610419565b6100a26100e836600461077d565b610528565b60006001600160e01b03198216630158951d60e31b148061011e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610134604082016020830161077d565b6001600160a01b0316634352409a61014f602084018461077d565b604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301528401356024820152604401602060405180830381865afa15801561019c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c0919061079a565b15156000036101e2576040516302aa5ad560e11b815260040160405180910390fd5b60006101f4604083016020840161077d565b6001600160a01b0316638c07607783604001356040518263ffffffff1660e01b815260040161022591815260200190565b602060405180830381865afa158015610242573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026691906107bc565b9050806001600160a01b0316637dcc80546040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102a357600080fd5b505af11580156102b7573d6000803e3d6000fd5b506102cc92505050604083016020840161077d565b6001600160a01b0316633fa9d54460408401356102ec602086018661077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035c919061079a565b5061036d604083016020840161077d565b6001600160a01b031663641f776e6040840135610390608086016060870161077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156103dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610400919061079a565b505050565b61040d6105a1565b61041760006105fb565b565b600054610100900460ff16158080156104395750600054600160ff909116105b806104535750303b158015610453575060005460ff166001145b6104bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156104de576000805461ff0019166101001790555b8015610524576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6105306105a1565b6001600160a01b0381166105955760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104b2565b61059e816105fb565b50565b6033546001600160a01b031633146104175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104b2565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561065f57600080fd5b81356001600160e01b03198116811461067757600080fd5b9392505050565b6000608082840312801561069157600080fd5b509092915050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156106c157600080fd5b813567ffffffffffffffff8111156106d857600080fd5b8201601f810184136106e957600080fd5b803567ffffffffffffffff81111561070357610703610699565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561073257610732610699565b60405281815282820160200186101561074a57600080fd5b81602084016020830137600091810160200191909152949350505050565b6001600160a01b038116811461059e57600080fd5b60006020828403121561078f57600080fd5b813561067781610768565b6000602082840312156107ac57600080fd5b8151801515811461067757600080fd5b6000602082840312156107ce57600080fd5b81516106778161076856fea26469706673582212203efa05c08e63f84221d377b68763b018336f724f765ab2f48bdef7fc96aa814b64736f6c634300081c0033", + "devdoc": { + "events": { + "Initialized(uint8)": { + "details": "Triggered when the contract has been initialized or reinitialized." + } + }, + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 3585, + "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 3588, + "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 6487, + "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 3379, + "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", + "label": "_owner", + "offset": 0, + "slot": "51", + "type": "t_address" + }, + { + "astId": 3499, + "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", + "label": "__gap", + "offset": 0, + "slot": "52", + "type": "t_array(t_uint256)49_storage" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "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_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/sepolia/DecentHatsCreationModule.json b/deployments/sepolia/DecentHatsCreationModule.json new file mode 100644 index 00000000..66f4399d --- /dev/null +++ b/deployments/sepolia/DecentHatsCreationModule.json @@ -0,0 +1,269 @@ +{ + "address": "0x7dF6463aC96e6dB04f5C1bCfed6B85e3dBB3736B", + "abi": [ + { + "inputs": [], + "name": "SALT", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "erc6551Registry", + "type": "address" + }, + { + "internalType": "contract IHatsModuleFactory", + "name": "hatsModuleFactory", + "type": "address" + }, + { + "internalType": "contract ModuleProxyFactory", + "name": "moduleProxyFactory", + "type": "address" + }, + { + "internalType": "address", + "name": "keyValuePairs", + "type": "address" + }, + { + "internalType": "address", + "name": "decentAutonomousAdminMasterCopy", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsElectionsEligibilityImplementation", + "type": "address" + }, + { + "components": [ + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + } + ], + "internalType": "struct DecentHatsCreationModule.TopHatParams", + "name": "topHat", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + } + ], + "internalType": "struct DecentHatsCreationModule.AdminHatParams", + "name": "adminHat", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "UD60x18", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct Broker", + "name": "broker", + "type": "tuple" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + } + ], + "internalType": "struct DecentHatsUtils.SablierStreamParams[]", + "name": "sablierStreamsParams", + "type": "tuple[]" + }, + { + "internalType": "uint128", + "name": "termEndDateTs", + "type": "uint128" + }, + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + } + ], + "internalType": "struct DecentHatsUtils.HatParams[]", + "name": "hats", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHatsCreationModule.CreateTreeParams", + "name": "params", + "type": "tuple" + } + ], + "name": "createAndDeclareTree", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0xb1b5f1d6dd76730deb8a5bf5a3468fa6e64d7be5b6376306a50815641214a53c", + "receipt": { + "to": null, + "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", + "contractAddress": "0x7dF6463aC96e6dB04f5C1bCfed6B85e3dBB3736B", + "transactionIndex": 64, + "gasUsed": "1702356", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcec81ccef94d76b5c375ad27fa058a5f8336e4f97b970766ef88e30f4edc8e27", + "transactionHash": "0xb1b5f1d6dd76730deb8a5bf5a3468fa6e64d7be5b6376306a50815641214a53c", + "logs": [], + "blockNumber": 6984774, + "cumulativeGasUsed": "13380445", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "7c4217108daa894b08d16e65df533416", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"SALT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"erc6551Registry\",\"type\":\"address\"},{\"internalType\":\"contract IHatsModuleFactory\",\"name\":\"hatsModuleFactory\",\"type\":\"address\"},{\"internalType\":\"contract ModuleProxyFactory\",\"name\":\"moduleProxyFactory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"decentAutonomousAdminMasterCopy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsElectionsEligibilityImplementation\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"}],\"internalType\":\"struct DecentHatsCreationModule.TopHatParams\",\"name\":\"topHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"}],\"internalType\":\"struct DecentHatsCreationModule.AdminHatParams\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"UD60x18\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct Broker\",\"name\":\"broker\",\"type\":\"tuple\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"}],\"internalType\":\"struct DecentHatsUtils.SablierStreamParams[]\",\"name\":\"sablierStreamsParams\",\"type\":\"tuple[]\"},{\"internalType\":\"uint128\",\"name\":\"termEndDateTs\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"}],\"internalType\":\"struct DecentHatsUtils.HatParams[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHatsCreationModule.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))\":{\"details\":\"For each hat that is included, if the hat is: - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-` on the Sablier contract. - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat to the calling safe.This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHatsCreationModule.sol\":\"DecentHatsCreationModule\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\ncontract ModuleProxyFactory {\\n event ModuleProxyCreation(\\n address indexed proxy,\\n address indexed masterCopy\\n );\\n\\n /// `target` can not be zero.\\n error ZeroAddress(address target);\\n\\n /// `address_` is already taken.\\n error TakenAddress(address address_);\\n\\n /// @notice Initialization failed.\\n error FailedInitialization();\\n\\n function createProxy(address target, bytes32 salt)\\n internal\\n returns (address result)\\n {\\n if (address(target) == address(0)) revert ZeroAddress(target);\\n bytes memory deployment = abi.encodePacked(\\n hex\\\"602d8060093d393df3363d3d373d3d3d363d73\\\",\\n target,\\n hex\\\"5af43d82803e903d91602b57fd5bf3\\\"\\n );\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\\n }\\n if (result == address(0)) revert TakenAddress(result);\\n }\\n\\n function deployModule(\\n address masterCopy,\\n bytes memory initializer,\\n uint256 saltNonce\\n ) public returns (address proxy) {\\n proxy = createProxy(\\n masterCopy,\\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\\n );\\n (bool success, ) = proxy.call(initializer);\\n if (!success) revert FailedInitialization();\\n\\n emit ModuleProxyCreation(proxy, masterCopy);\\n }\\n}\\n\",\"keccak256\":\"0x70f6f1d88cf3382748e58f85ba87279f5bb8761863c293dd8c197a71ff558761\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentHatsCreationModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {LockupLinear, Broker} from \\\"./interfaces/sablier/types/DataTypes.sol\\\";\\nimport {IHatsModuleFactory} from \\\"./interfaces/hats/IHatsModuleFactory.sol\\\";\\nimport {IHatsElectionsEligibility} from \\\"./interfaces/hats/modules/IHatsElectionsEligibility.sol\\\";\\nimport {ModuleProxyFactory} from \\\"@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {DecentHatsUtils} from \\\"./DecentHatsUtils.sol\\\";\\n\\ncontract DecentHatsCreationModule is DecentHatsUtils {\\n struct TopHatParams {\\n string details;\\n string imageURI;\\n }\\n\\n struct AdminHatParams {\\n string details;\\n string imageURI;\\n bool isMutable;\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n IERC6551Registry erc6551Registry;\\n IHatsModuleFactory hatsModuleFactory;\\n ModuleProxyFactory moduleProxyFactory;\\n address keyValuePairs;\\n address decentAutonomousAdminMasterCopy;\\n address hatsAccountImplementation;\\n address hatsElectionsEligibilityImplementation;\\n TopHatParams topHat;\\n AdminHatParams adminHat;\\n HatParams[] hats;\\n }\\n\\n /* /////////////////////////////////////////////////////////////////////////////\\n EXTERNAL FUNCTIONS\\n ///////////////////////////////////////////////////////////////////////////// */\\n /**\\n * @notice For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat\\n * to the calling safe.\\n *\\n * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev For each hat that is included, if the hat is:\\n * - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-`\\n * on the Sablier contract.\\n * - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the\\n * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) external {\\n IHats hatsProtocol = params.hatsProtocol;\\n address hatsAccountImplementation = params.hatsAccountImplementation;\\n IERC6551Registry erc6551Registry = params.erc6551Registry;\\n\\n // Create Top Hat\\n (uint256 topHatId, address topHatAccount) = _processTopHat(\\n hatsProtocol,\\n erc6551Registry,\\n hatsAccountImplementation,\\n params.keyValuePairs,\\n params.topHat\\n );\\n\\n // Create Admin Hat\\n uint256 adminHatId = _processAdminHat(\\n hatsProtocol,\\n erc6551Registry,\\n hatsAccountImplementation,\\n topHatId,\\n topHatAccount,\\n params.moduleProxyFactory,\\n params.decentAutonomousAdminMasterCopy,\\n params.adminHat\\n );\\n\\n // Create Role Hats\\n for (uint256 i = 0; i < params.hats.length; ) {\\n HatParams memory hat = params.hats[i];\\n _processHat(\\n hatsProtocol,\\n erc6551Registry,\\n hatsAccountImplementation,\\n topHatId,\\n topHatAccount,\\n params.hatsModuleFactory,\\n params.hatsElectionsEligibilityImplementation,\\n adminHatId,\\n hat\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /* /////////////////////////////////////////////////////////////////////////////\\n INTERNAL FUNCTIONS\\n ///////////////////////////////////////////////////////////////////////////// */\\n\\n function _processTopHat(\\n IHats hatsProtocol,\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n address keyValuePairs,\\n TopHatParams memory topHat\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n // Call lastTopHatId() and properly decode the response\\n (bool success, bytes memory data) = address(hatsProtocol).call(\\n abi.encodeWithSignature(\\\"lastTopHatId()\\\")\\n );\\n require(success, \\\"Failed to get lastTopHatId\\\");\\n topHatId = (abi.decode(data, (uint256)) + 1) << 224;\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n // Mint top hat to the safe\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"mintTopHat(address,string,string)\\\",\\n msg.sender,\\n topHat.details,\\n topHat.imageURI\\n ),\\n Enum.Operation.Call\\n );\\n\\n // Create top hat account\\n topHatAccount = erc6551Registry.createAccount(\\n hatsAccountImplementation,\\n SALT,\\n block.chainid,\\n address(hatsProtocol),\\n topHatId\\n );\\n\\n // Declare Top Hat ID to Safe via KeyValuePairs\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n IAvatar(msg.sender).execTransactionFromModule(\\n keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function _processAdminHat(\\n IHats hatsProtocol,\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n uint256 topHatId,\\n address topHatAccount,\\n ModuleProxyFactory moduleProxyFactory,\\n address decentAutonomousAdminMasterCopy,\\n AdminHatParams memory adminHat\\n ) internal returns (uint256 adminHatId) {\\n // Create Admin Hat\\n adminHatId = hatsProtocol.getNextId(topHatId);\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createHat(uint256,string,uint32,address,address,bool,string)\\\",\\n topHatId,\\n adminHat.details,\\n 1, // only one Admin Hat\\n topHatAccount,\\n topHatAccount,\\n adminHat.isMutable,\\n adminHat.imageURI\\n ),\\n Enum.Operation.Call\\n );\\n\\n // Create Admin Hat's ERC6551 Account\\n erc6551Registry.createAccount(\\n hatsAccountImplementation,\\n SALT,\\n block.chainid,\\n address(hatsProtocol),\\n adminHatId\\n );\\n\\n // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat\\n address autonomousAdminModule = moduleProxyFactory.deployModule(\\n decentAutonomousAdminMasterCopy,\\n abi.encodeWithSignature(\\\"setUp(bytes)\\\", bytes(\\\"\\\")),\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n // for the salt, we'll concatenate our static salt with the id of the Admin Hat\\n SALT,\\n adminHatId\\n )\\n )\\n )\\n );\\n\\n // Mint Hat to the Decent Autonomous Admin Module\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"mintHat(uint256,address)\\\",\\n adminHatId,\\n autonomousAdminModule\\n ),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xa9750e9587839acd750d4df777e864389f3d2c138c27dbdc81b6a6a37d9cc61e\",\"license\":\"MIT\"},\"contracts/DecentHatsUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {LockupLinear, Broker} from \\\"./interfaces/sablier/types/DataTypes.sol\\\";\\nimport {IHatsModuleFactory} from \\\"./interfaces/hats/IHatsModuleFactory.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\n\\nabstract contract DecentHatsUtils {\\n bytes32 public constant SALT =\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n address asset;\\n LockupLinear.Timestamps timestamps;\\n Broker broker;\\n uint128 totalAmount;\\n bool cancelable;\\n bool transferable;\\n }\\n\\n struct HatParams {\\n address wearer;\\n string details;\\n string imageURI;\\n SablierStreamParams[] sablierStreamsParams;\\n uint128 termEndDateTs; // If 0, this is an untermed Hat\\n uint32 maxSupply;\\n bool isMutable;\\n }\\n\\n function _processHat(\\n IHats hatsProtocol,\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n uint256 topHatId,\\n address topHatAccount,\\n IHatsModuleFactory hatsModuleFactory,\\n address hatsElectionsEligibilityImplementation,\\n uint256 adminHatId,\\n HatParams memory hat\\n ) internal {\\n // Create eligibility module if needed\\n address eligibilityAddress = _createEligibilityModule(\\n hatsProtocol,\\n hatsModuleFactory,\\n hatsElectionsEligibilityImplementation,\\n topHatId,\\n topHatAccount,\\n adminHatId,\\n hat.termEndDateTs\\n );\\n\\n // Create and Mint the Role Hat\\n uint256 hatId = _createAndMintHat(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n eligibilityAddress,\\n topHatAccount\\n );\\n\\n // Get the stream recipient (based on termed or not)\\n address streamRecipient = _setupStreamRecipient(\\n erc6551Registry,\\n hatsAccountImplementation,\\n address(hatsProtocol),\\n hat.termEndDateTs,\\n hat.wearer,\\n hatId\\n );\\n\\n // Create streams\\n _processSablierStreams(hat.sablierStreamsParams, streamRecipient);\\n }\\n\\n function _createEligibilityModule(\\n IHats hatsProtocol,\\n IHatsModuleFactory hatsModuleFactory,\\n address hatsElectionsEligibilityImplementation,\\n uint256 topHatId,\\n address topHatAccount,\\n uint256 adminHatId,\\n uint128 termEndDateTs\\n ) private returns (address) {\\n if (termEndDateTs != 0) {\\n return\\n hatsModuleFactory.createHatsModule(\\n hatsElectionsEligibilityImplementation,\\n hatsProtocol.getNextId(adminHatId),\\n abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID]\\n abi.encode(termEndDateTs),\\n uint256(SALT)\\n );\\n }\\n return topHatAccount;\\n }\\n\\n function _createAndMintHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n HatParams memory hat,\\n address eligibilityAddress,\\n address topHatAccount\\n ) private returns (uint256) {\\n uint256 hatId = hatsProtocol.getNextId(adminHatId);\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createHat(uint256,string,uint32,address,address,bool,string)\\\",\\n adminHatId,\\n hat.details,\\n hat.maxSupply,\\n eligibilityAddress,\\n topHatAccount,\\n hat.isMutable,\\n hat.imageURI\\n ),\\n Enum.Operation.Call\\n );\\n\\n // If the hat is termed, nominate the wearer as the eligible member\\n if (hat.termEndDateTs != 0) {\\n address[] memory nominatedWearers = new address[](1);\\n nominatedWearers[0] = hat.wearer;\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n eligibilityAddress,\\n 0,\\n abi.encodeWithSignature(\\n \\\"elect(uint128,address[])\\\",\\n hat.termEndDateTs,\\n nominatedWearers\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"mintHat(uint256,address)\\\",\\n hatId,\\n hat.wearer\\n ),\\n Enum.Operation.Call\\n );\\n return hatId;\\n }\\n\\n // Exists to avoid stack too deep errors\\n function _setupStreamRecipient(\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n address hatsProtocol,\\n uint128 termEndDateTs,\\n address wearer,\\n uint256 hatId\\n ) private returns (address) {\\n // If the hat is termed, the wearer is the stream recipient\\n if (termEndDateTs != 0) {\\n return wearer;\\n }\\n\\n // Otherwise, the Hat's smart account is the stream recipient\\n return\\n erc6551Registry.createAccount(\\n hatsAccountImplementation,\\n SALT,\\n block.chainid,\\n hatsProtocol,\\n hatId\\n );\\n }\\n\\n function _processSablierStreams(\\n SablierStreamParams[] memory streamParams,\\n address streamRecipient\\n ) private {\\n for (uint256 i = 0; i < streamParams.length; ) {\\n SablierStreamParams memory sablierStreamParams = streamParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierStreamParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n sablierStreamParams.sablier,\\n sablierStreamParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierStreamParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n LockupLinear.CreateWithTimestamps({\\n sender: sablierStreamParams.sender,\\n recipient: streamRecipient,\\n totalAmount: sablierStreamParams.totalAmount,\\n asset: IERC20(sablierStreamParams.asset),\\n cancelable: sablierStreamParams.cancelable,\\n transferable: sablierStreamParams.transferable,\\n timestamps: sablierStreamParams.timestamps,\\n broker: sablierStreamParams.broker\\n })\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x098730a395481cb4b17996b677f284c3e83a631a1429a15aa98b793dd2879c19\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/HatsErrors.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsErrors {\\n /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats\\n /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree`\\n error NotAdmin(address user, uint256 hatId);\\n\\n /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat\\n error NotHatWearer();\\n\\n /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat\\n error NotAdminOrWearer();\\n\\n /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached\\n error AllHatsWorn(uint256 hatId);\\n\\n /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin\\n error MaxLevelsReached();\\n\\n /// @notice Emitted when an attempted hat id has empty intermediate level(s)\\n error InvalidHatId();\\n\\n /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat\\n error AlreadyWearingHat(address wearer, uint256 hatId);\\n\\n /// @notice Emitted when attempting to mint a non-existant hat\\n error HatDoesNotExist(uint256 hatId);\\n\\n /// @notice Emmitted when attempting to mint or transfer a hat that is not active\\n error HatNotActive();\\n\\n /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer\\n error NotEligible();\\n\\n /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module\\n error NotHatsToggle();\\n\\n /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module\\n error NotHatsEligibility();\\n\\n /// @notice Emitted when array arguments to a batch function have mismatching lengths\\n error BatchArrayLengthMismatch();\\n\\n /// @notice Emitted when attempting to mutate or transfer an immutable hat\\n error Immutable();\\n\\n /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply\\n error NewMaxSupplyTooLow();\\n\\n /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin\\n error CircularLinkage();\\n\\n /// @notice Emitted when attempting to link or relink a tophat to a separate tree\\n error CrossTreeLinkage();\\n\\n /// @notice Emitted when attempting to link a tophat without a request\\n error LinkageNotRequested();\\n\\n /// @notice Emitted when attempting to unlink a tophat that does not have a wearer\\n /// @dev This ensures that unlinking never results in a bricked tophat\\n error InvalidUnlink();\\n\\n /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address\\n error ZeroAddress();\\n\\n /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters)\\n /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI\\n /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()`\\n error StringTooLong();\\n}\\n\",\"keccak256\":\"0x81b0056b7bed86eabc07c0e4a9655c586ddb8e6c128320593669b76efd5a08de\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/HatsEvents.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsEvents {\\n /// @notice Emitted when a new hat is created\\n /// @param id The id for the new hat\\n /// @param details A description of the Hat\\n /// @param maxSupply The total instances of the Hat that can be worn at once\\n /// @param eligibility The address that can report on the Hat wearer's status\\n /// @param toggle The address that can deactivate the Hat\\n /// @param mutable_ Whether the hat's properties are changeable after creation\\n /// @param imageURI The image uri for this hat and the fallback for its\\n event HatCreated(\\n uint256 id,\\n string details,\\n uint32 maxSupply,\\n address eligibility,\\n address toggle,\\n bool mutable_,\\n string imageURI\\n );\\n\\n /// @notice Emitted when a hat wearer's standing is updated\\n /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction\\n /// @param hatId The id of the wearer's hat\\n /// @param wearer The wearer's address\\n /// @param wearerStanding Whether the wearer is in good standing for the hat\\n event WearerStandingChanged(\\n uint256 hatId,\\n address wearer,\\n bool wearerStanding\\n );\\n\\n /// @notice Emitted when a hat's status is updated\\n /// @param hatId The id of the hat\\n /// @param newStatus Whether the hat is active\\n event HatStatusChanged(uint256 hatId, bool newStatus);\\n\\n /// @notice Emitted when a hat's details are updated\\n /// @param hatId The id of the hat\\n /// @param newDetails The updated details\\n event HatDetailsChanged(uint256 hatId, string newDetails);\\n\\n /// @notice Emitted when a hat's eligibility module is updated\\n /// @param hatId The id of the hat\\n /// @param newEligibility The updated eligibiliy module\\n event HatEligibilityChanged(uint256 hatId, address newEligibility);\\n\\n /// @notice Emitted when a hat's toggle module is updated\\n /// @param hatId The id of the hat\\n /// @param newToggle The updated toggle module\\n event HatToggleChanged(uint256 hatId, address newToggle);\\n\\n /// @notice Emitted when a hat's mutability is updated\\n /// @param hatId The id of the hat\\n event HatMutabilityChanged(uint256 hatId);\\n\\n /// @notice Emitted when a hat's maximum supply is updated\\n /// @param hatId The id of the hat\\n /// @param newMaxSupply The updated max supply\\n event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply);\\n\\n /// @notice Emitted when a hat's image URI is updated\\n /// @param hatId The id of the hat\\n /// @param newImageURI The updated image URI\\n event HatImageURIChanged(uint256 hatId, string newImageURI);\\n\\n /// @notice Emitted when a tophat linkage is requested by its admin\\n /// @param domain The domain of the tree tophat to link\\n /// @param newAdmin The tophat's would-be admin in the parent tree\\n event TopHatLinkRequested(uint32 domain, uint256 newAdmin);\\n\\n /// @notice Emitted when a tophat is linked to a another tree\\n /// @param domain The domain of the newly-linked tophat\\n /// @param newAdmin The tophat's new admin in the parent tree\\n event TopHatLinked(uint32 domain, uint256 newAdmin);\\n}\\n\",\"keccak256\":\"0x53413397d15e1636c3cd7bd667656b79bc2886785403b824bcd4ed122667f2c6\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\nimport \\\"./IHatsIdUtilities.sol\\\";\\nimport \\\"./HatsErrors.sol\\\";\\nimport \\\"./HatsEvents.sol\\\";\\n\\ninterface IHats is IHatsIdUtilities, HatsErrors, HatsEvents {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function batchCreateHats(\\n uint256[] calldata _admins,\\n string[] calldata _details,\\n uint32[] calldata _maxSupplies,\\n address[] memory _eligibilityModules,\\n address[] memory _toggleModules,\\n bool[] calldata _mutables,\\n string[] calldata _imageURIs\\n ) external returns (bool success);\\n\\n function getNextId(uint256 _admin) external view returns (uint256 nextId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function batchMintHats(\\n uint256[] calldata _hatIds,\\n address[] calldata _wearers\\n ) external returns (bool success);\\n\\n function setHatStatus(\\n uint256 _hatId,\\n bool _newStatus\\n ) external returns (bool toggled);\\n\\n function checkHatStatus(uint256 _hatId) external returns (bool toggled);\\n\\n function setHatWearerStatus(\\n uint256 _hatId,\\n address _wearer,\\n bool _eligible,\\n bool _standing\\n ) external returns (bool updated);\\n\\n function checkHatWearerStatus(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool updated);\\n\\n function renounceHat(uint256 _hatId) external;\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n HATS ADMIN FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function makeHatImmutable(uint256 _hatId) external;\\n\\n function changeHatDetails(\\n uint256 _hatId,\\n string memory _newDetails\\n ) external;\\n\\n function changeHatEligibility(\\n uint256 _hatId,\\n address _newEligibility\\n ) external;\\n\\n function changeHatToggle(uint256 _hatId, address _newToggle) external;\\n\\n function changeHatImageURI(\\n uint256 _hatId,\\n string memory _newImageURI\\n ) external;\\n\\n function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external;\\n\\n function requestLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat\\n ) external;\\n\\n function approveLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external;\\n\\n function relinkTopHatWithinTree(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n VIEW FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function viewHat(\\n uint256 _hatId\\n )\\n external\\n view\\n returns (\\n string memory details,\\n uint32 maxSupply,\\n uint32 supply,\\n address eligibility,\\n address toggle,\\n string memory imageURI,\\n uint16 lastHatId,\\n bool mutable_,\\n bool active\\n );\\n\\n function isWearerOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isWearer);\\n\\n function isAdminOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isAdmin);\\n\\n function isInGoodStanding(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool standing);\\n\\n function isEligible(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible);\\n\\n function getHatEligibilityModule(\\n uint256 _hatId\\n ) external view returns (address eligibility);\\n\\n function getHatToggleModule(\\n uint256 _hatId\\n ) external view returns (address toggle);\\n\\n function getHatMaxSupply(\\n uint256 _hatId\\n ) external view returns (uint32 maxSupply);\\n\\n function hatSupply(uint256 _hatId) external view returns (uint32 supply);\\n\\n function getImageURIForHat(\\n uint256 _hatId\\n ) external view returns (string memory _uri);\\n\\n function balanceOf(\\n address wearer,\\n uint256 hatId\\n ) external view returns (uint256 balance);\\n\\n function balanceOfBatch(\\n address[] calldata _wearers,\\n uint256[] calldata _hatIds\\n ) external view returns (uint256[] memory);\\n\\n function uri(uint256 id) external view returns (string memory _uri);\\n}\\n\",\"keccak256\":\"0x2867004bddc5148fa1937f25c0403e5d9977583aaf50fdbdb74bd463f64f21c8\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHatsIdUtilities.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHatsIdUtilities {\\n function buildHatId(\\n uint256 _admin,\\n uint16 _newHat\\n ) external pure returns (uint256 id);\\n\\n function getHatLevel(uint256 _hatId) external view returns (uint32 level);\\n\\n function getLocalHatLevel(\\n uint256 _hatId\\n ) external pure returns (uint32 level);\\n\\n function isTopHat(uint256 _hatId) external view returns (bool _topHat);\\n\\n function isLocalTopHat(\\n uint256 _hatId\\n ) external pure returns (bool _localTopHat);\\n\\n function isValidHatId(\\n uint256 _hatId\\n ) external view returns (bool validHatId);\\n\\n function getAdminAtLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external view returns (uint256 admin);\\n\\n function getAdminAtLocalLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external pure returns (uint256 admin);\\n\\n function getTopHatDomain(\\n uint256 _hatId\\n ) external view returns (uint32 domain);\\n\\n function getTippyTopHatDomain(\\n uint32 _topHatDomain\\n ) external view returns (uint32 domain);\\n\\n function noCircularLinkage(\\n uint32 _topHatDomain,\\n uint256 _linkedAdmin\\n ) external view returns (bool notCircular);\\n\\n function sameTippyTopHatDomain(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat\\n ) external view returns (bool sameDomain);\\n}\\n\",\"keccak256\":\"0x007fcc07b20bf84bacad1f9a2ddf4e30e1a8be961e144b7bef8e98a51781aee9\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHatsModuleFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IHatsModuleFactory {\\n error HatsModuleFactory_ModuleAlreadyDeployed(\\n address implementation,\\n uint256 hatId,\\n bytes otherImmutableArgs,\\n uint256 saltNonce\\n );\\n\\n error BatchArrayLengthMismatch();\\n\\n event HatsModuleFactory_ModuleDeployed(\\n address implementation,\\n address instance,\\n uint256 hatId,\\n bytes otherImmutableArgs,\\n bytes initData,\\n uint256 saltNonce\\n );\\n\\n function HATS() external view returns (address);\\n\\n function version() external view returns (string memory);\\n\\n function createHatsModule(\\n address _implementation,\\n uint256 _hatId,\\n bytes calldata _otherImmutableArgs,\\n bytes calldata _initData,\\n uint256 _saltNonce\\n ) external returns (address _instance);\\n\\n function batchCreateHatsModule(\\n address[] calldata _implementations,\\n uint256[] calldata _hatIds,\\n bytes[] calldata _otherImmutableArgsArray,\\n bytes[] calldata _initDataArray,\\n uint256[] calldata _saltNonces\\n ) external returns (bool success);\\n\\n function getHatsModuleAddress(\\n address _implementation,\\n uint256 _hatId,\\n bytes calldata _otherImmutableArgs,\\n uint256 _saltNonce\\n ) external view returns (address);\\n\\n function deployed(\\n address _implementation,\\n uint256 _hatId,\\n bytes calldata _otherImmutableArgs,\\n uint256 _saltNonce\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x861faf40785cedb829243116d492653414a367853408a5c27d201522f6c3bfdd\",\"license\":\"MIT\"},\"contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.13;\\n\\ninterface IHatsElectionsEligibility {\\n event ElectionOpened(uint128 nextTermEnd);\\n event ElectionCompleted(uint128 termEnd, address[] winners);\\n event NewTermStarted(uint128 termEnd);\\n event Recalled(uint128 termEnd, address[] accounts);\\n\\n /// @notice Returns the first second after the current term ends.\\n /// @dev Also serves as the id for the current term.\\n function currentTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the first second after the next term ends.\\n /// @dev Also serves as the id for the next term.\\n function nextTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the election status (open or closed) for a given term end.\\n /// @param termEnd The term end timestamp to query.\\n function electionStatus(\\n uint128 termEnd\\n ) external view returns (bool isElectionOpen);\\n\\n /// @notice Returns whether a candidate was elected in a given term.\\n /// @param termEnd The term end timestamp to query.\\n /// @param candidate The address of the candidate.\\n function electionResults(\\n uint128 termEnd,\\n address candidate\\n ) external view returns (bool elected);\\n\\n /// @notice Returns the BALLOT_BOX_HAT constant.\\n function BALLOT_BOX_HAT() external pure returns (uint256);\\n\\n /// @notice Returns the ADMIN_HAT constant.\\n function ADMIN_HAT() external pure returns (uint256);\\n\\n /**\\n * @notice Submit the results of an election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the election results are being submitted.\\n * @param _winners The addresses of the winners of the election.\\n */\\n function elect(uint128 _termEnd, address[] calldata _winners) external;\\n\\n /**\\n * @notice Submit the results of a recall election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the recall results are being submitted.\\n * @param _recallees The addresses to be recalled.\\n */\\n function recall(uint128 _termEnd, address[] calldata _recallees) external;\\n\\n /**\\n * @notice Set the next term and open the election for it.\\n * @dev Only callable by the wearer(s) of the ADMIN_HAT.\\n * @param _newTermEnd The id of the term that will be opened.\\n */\\n function setNextTerm(uint128 _newTermEnd) external;\\n\\n /**\\n * @notice Start the next term, updating the current term.\\n * @dev Can be called by anyone, but will revert if conditions are not met.\\n */\\n function startNextTerm() external;\\n\\n /**\\n * @notice Determine the eligibility and standing of a wearer for a hat.\\n * @param _wearer The address of the hat wearer.\\n * @param _hatId The ID of the hat.\\n * @return eligible True if the wearer is eligible for the hat.\\n * @return standing True if the wearer is in good standing.\\n */\\n function getWearerStatus(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible, bool standing);\\n}\\n\",\"keccak256\":\"0x74dfc5d538d866ddb8ee2ca1b569abf62e02d848c59f308adf6075ecff175c7d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport {Lockup, LockupLinear} from \\\"./types/DataTypes.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./ISablierV2Lockup.sol\\\";\\n\\n/// @title ISablierV2LockupLinear\\n/// @notice Creates and manages Lockup streams with a linear distribution function.\\ninterface ISablierV2LockupLinear is ISablierV2Lockup {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when a stream is created.\\n /// @param streamId The ID of the newly created stream.\\n /// @param funder The address which funded the stream.\\n /// @param sender The address distributing the assets, which will have the ability to cancel the stream.\\n /// @param recipient The address receiving the assets.\\n /// @param amounts Struct encapsulating (i) the deposit amount, and (ii) the broker fee amount, both denoted\\n /// in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Boolean indicating whether the stream will be cancelable or not.\\n /// @param transferable Boolean indicating whether the stream NFT is transferable or not.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker The address of the broker who has helped create the stream, e.g. a front-end website.\\n event CreateLockupLinearStream(\\n uint256 streamId,\\n address funder,\\n address indexed sender,\\n address indexed recipient,\\n Lockup.CreateAmounts amounts,\\n IERC20 indexed asset,\\n bool cancelable,\\n bool transferable,\\n LockupLinear.Timestamps timestamps,\\n address broker\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the stream's cliff time, which is a Unix timestamp. A value of zero means there\\n /// is no cliff.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getCliffTime(\\n uint256 streamId\\n ) external view returns (uint40 cliffTime);\\n\\n /// @notice Retrieves the full stream details.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n /// @return stream See the documentation in {DataTypes}.\\n function getStream(\\n uint256 streamId\\n ) external view returns (LockupLinear.StreamLL memory stream);\\n\\n /// @notice Retrieves the stream's start, cliff and end timestamps.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n /// @return timestamps See the documentation in {DataTypes}.\\n function getTimestamps(\\n uint256 streamId\\n ) external view returns (LockupLinear.Timestamps memory timestamps);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Creates a stream by setting the start time to `block.timestamp`, and the end time to\\n /// the sum of `block.timestamp` and `params.durations.total`. The stream is funded by `msg.sender` and is wrapped\\n /// in an ERC-721 NFT.\\n ///\\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\\n ///\\n /// Requirements:\\n /// - All requirements in {createWithTimestamps} must be met for the calculated parameters.\\n ///\\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\\n /// @return streamId The ID of the newly created stream.\\n function createWithDurations(\\n LockupLinear.CreateWithDurations calldata params\\n ) external returns (uint256 streamId);\\n\\n /// @notice Creates a stream with the provided start time and end time. The stream is funded by `msg.sender` and is\\n /// wrapped in an ERC-721 NFT.\\n ///\\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\\n ///\\n /// Notes:\\n /// - A cliff time of zero means there is no cliff.\\n /// - As long as the times are ordered, it is not an error for the start or the cliff time to be in the past.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `params.totalAmount` must be greater than zero.\\n /// - If set, `params.broker.fee` must not be greater than `MAX_BROKER_FEE`.\\n /// - `params.timestamps.start` must be greater than zero and less than `params.timestamps.end`.\\n /// - If set, `params.timestamps.cliff` must be greater than `params.timestamps.start` and less than\\n /// `params.timestamps.end`.\\n /// - `params.timestamps.end` must be in the future.\\n /// - `params.recipient` must not be the zero address.\\n /// - `msg.sender` must have allowed this contract to spend at least `params.totalAmount` assets.\\n ///\\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\\n /// @return streamId The ID of the newly created stream.\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0x064264723114b1f1cf3953fd79874dfcbb42cf313857aee6d5e6b09a23e0010b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b50611dd58061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063ba9a91a51461003b578063d58041b714610062575b600080fd5b610050600080516020611d8083398151915281565b60405190815260200160405180910390f35b61007561007036600461122f565b610077565b005b60006100866020830183611289565b9050600061009a60e0840160c08501611289565b905060006100ae6040850160208601611289565b90506000806100e58584866100c960a08b0160808c01611289565b6100d76101008c018c6112b6565b6100e09061141a565b6101d7565b90925090506000610136868587868661010460808e0160608f01611289565b8d60a00160208101906101179190611289565b8e806101200190610128919061148a565b610131906114b9565b6105ad565b905060005b61014961014089018961153c565b90508110156101cd5760006101626101408a018a61153c565b838181106101725761017261158c565b905060200281019061018491906115a2565b61018d9061179b565b90506101c488878988888e60400160208101906101aa9190611289565b8f60e00160208101906101bd9190611289565b8a89610938565b5060010161013b565b5050505050505050565b60408051600481526024810182526020810180516001600160e01b0316633f0f816960e21b17905290516000918291829182916001600160a01b038b169161021e9161189e565b6000604051808303816000865af19150503d806000811461025b576040519150601f19603f3d011682016040523d82523d6000602084013e610260565b606091505b5091509150816102b65760405162461bcd60e51b815260206004820152601a60248201527f4661696c656420746f20676574206c617374546f704861744964000000000000604482015260640160405180910390fd5b60e0818060200190518101906102cc91906118b0565b6102d79060016118df565b901b9350336001600160a01b031663468721a78a60003389600001518a6020015160405160240161030a93929190611924565b60408051601f198184030181529181526020820180516001600160e01b0316631a64dfad60e01b1790525160e085901b6001600160e01b03191681526103589392919060009060040161195a565b6020604051808303816000875af1158015610377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039b91906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f906103de908a90600080516020611d808339815191529046908f908b906004016119cd565b6020604051808303816000875af11580156103fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104219190611a00565b60408051600180825281830190925291945060009190816020015b606081526020019060019003908161043c57505060408051600180825281830190925291925060009190602082015b606081526020019060019003908161046b579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b815250826000815181106104b6576104b661158c565b60200260200101819052506104ca86610996565b816000815181106104dd576104dd61158c565b6020026020010181905250336001600160a01b031663468721a7896000858560405160240161050d929190611a79565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b031916815261055b9392919060009060040161195a565b6020604051808303816000875af115801561057a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059e91906119b0565b50505050509550959350505050565b60405162460ea360e61b8152600481018690526000906001600160a01b038a1690631183a8c090602401602060405180830381865afa1580156105f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061891906118b0565b9050336001600160a01b031663468721a78a600089866000015160018b8c8a604001518b602001516040516024016106569796959493929190611aa7565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b03191681526106a49392919060009060040161195a565b6020604051808303816000875af11580156106c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e791906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f9061072a908a90600080516020611d808339815191529046908f9088906004016119cd565b6020604051808303816000875af1158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190611a00565b506000846001600160a01b031663f1ab873c85604051806020016040528060008152506040516024016107a09190611b08565b60408051601f19818403018152918152602080830180516001600160e01b031663a4f9edbf60e01b17905290516107f291600080516020611d8083398151915291899101918252602082015260400190565b60408051601f198184030181529082905280516020909101206001600160e01b031960e086901b16825261082a939291600401611b1b565b6020604051808303816000875af1158015610849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086d9190611a00565b604051602481018490526001600160a01b0382166044820152909150339063468721a7908c9060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b03191681526108e79392919060009060040161195a565b6020604051808303816000875af1158015610906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092a91906119b0565b505098975050505050505050565b600061094d8a86868a8a888860800151610a9e565b9050600061095e8b8585858b610c05565b905060006109788b8b8e8760800151886000015187610f37565b9050610988846060015182610fe1565b505050505050505050505050565b6060816000036109bd5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156109e757806109d181611b4f565b91506109e09050600a83611b7e565b91506109c1565b6000816001600160401b03811115610a0157610a016112d6565b6040519080825280601f01601f191660200182016040528015610a2b576020820181803683370190505b5090505b8415610a9657610a40600183611b92565b9150610a4d600a86611ba5565b610a589060306118df565b60f81b818381518110610a6d57610a6d61158c565b60200101906001600160f81b031916908160001a905350610a8f600a86611b7e565b9450610a2f565b949350505050565b60006001600160801b03821615610bf757866001600160a01b0316632f7fb7b6878a6001600160a01b0316631183a8c0876040518263ffffffff1660e01b8152600401610aed91815260200190565b602060405180830381865afa158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e91906118b0565b886000604051602001610b4b929190918252602082015260400190565b60408051601f198184030181528282526001600160801b0389166020840152910160408051601f19818403018152908290526001600160e01b031960e087901b168252610bad94939291600080516020611d8083398151915290600401611bb9565b6020604051808303816000875af1158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611a00565b9050610bfa565b50825b979650505050505050565b60405162460ea360e61b81526004810185905260009081906001600160a01b03881690631183a8c090602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7291906118b0565b9050336001600160a01b031663468721a78860008989602001518a60a001518a8a8d60c001518e60400151604051602401610cb39796959493929190611c05565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b0319168152610d019392919060009060040161195a565b6020604051808303816000875af1158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4491906119b0565b5060808501516001600160801b031615610e6f5760408051600180825281830190925260009160208083019080368337019050509050856000015181600081518110610d9257610d9261158c565b60200260200101906001600160a01b031690816001600160a01b031681525050336001600160a01b031663468721a7866000896080015185604051602401610ddb929190611c5b565b60408051601f198184030181529181526020820180516001600160e01b0316634a231cef60e01b1790525160e085901b6001600160e01b0319168152610e299392919060009060040161195a565b6020604051808303816000875af1158015610e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6c91906119b0565b50505b8451604051602481018390526001600160a01b039091166044820152339063468721a790899060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b0319168152610ee99392919060009060040161195a565b6020604051808303816000875af1158015610f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2c91906119b0565b509695505050505050565b60006001600160801b03841615610f4f575081610fd7565b604051638a54c52f60e01b81526001600160a01b03881690638a54c52f90610f91908990600080516020611d808339815191529046908b9089906004016119cd565b6020604051808303816000875af1158015610fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd49190611a00565b90505b9695505050505050565b60005b825181101561122a5760008382815181106110015761100161158c565b60200260200101519050336001600160a01b031663468721a78260400151600084600001518560a001516040516024016110599291906001600160a01b039290921682526001600160801b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526110a79392919060009060040161195a565b6020604051808303816000875af11580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea91906119b0565b50336001600160a01b031663468721a78260000151600060405180610100016040528086602001516001600160a01b03168152602001886001600160a01b031681526020018660a001516001600160801b0316815260200186604001516001600160a01b031681526020018660c00151151581526020018660e001511515815260200186606001518152602001866080015181525060405160240161118f9190611cb0565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526111dd9392919060009060040161195a565b6020604051808303816000875af11580156111fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122091906119b0565b5050600101610fe4565b505050565b60006020828403121561124157600080fd5b81356001600160401b0381111561125757600080fd5b8201610160818503121561126a57600080fd5b9392505050565b6001600160a01b038116811461128657600080fd5b50565b60006020828403121561129b57600080fd5b813561126a81611271565b80356112b181611271565b919050565b60008235603e198336030181126112cc57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561130e5761130e6112d6565b60405290565b604051606081016001600160401b038111828210171561130e5761130e6112d6565b60405161010081016001600160401b038111828210171561130e5761130e6112d6565b60405160e081016001600160401b038111828210171561130e5761130e6112d6565b604051601f8201601f191681016001600160401b03811182821017156113a3576113a36112d6565b604052919050565b600082601f8301126113bc57600080fd5b81356001600160401b038111156113d5576113d56112d6565b6113e8601f8201601f191660200161137b565b8181528460208386010111156113fd57600080fd5b816020850160208301376000918101602001919091529392505050565b60006040823603121561142c57600080fd5b6114346112ec565b82356001600160401b0381111561144a57600080fd5b611456368286016113ab565b82525060208301356001600160401b0381111561147257600080fd5b61147e368286016113ab565b60208301525092915050565b60008235605e198336030181126112cc57600080fd5b801515811461128657600080fd5b80356112b1816114a0565b6000606082360312156114cb57600080fd5b6114d3611314565b82356001600160401b038111156114e957600080fd5b6114f5368286016113ab565b82525060208301356001600160401b0381111561151157600080fd5b61151d368286016113ab565b6020830152506040830135611531816114a0565b604082015292915050565b6000808335601e1984360301811261155357600080fd5b8301803591506001600160401b0382111561156d57600080fd5b6020019150600581901b360382131561158557600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b6000823560de198336030181126112cc57600080fd5b803564ffffffffff811681146112b157600080fd5b6000606082840312156115df57600080fd5b6115e7611314565b90506115f2826115b8565b8152611600602083016115b8565b6020820152611531604083016115b8565b60006040828403121561162357600080fd5b61162b6112ec565b9050813561163881611271565b808252506020820135602082015292915050565b80356001600160801b03811681146112b157600080fd5b600082601f83011261167457600080fd5b81356001600160401b0381111561168d5761168d6112d6565b61169c60208260051b0161137b565b80828252602082019150602061016084028601019250858311156116bf57600080fd5b602085015b8381101561177d5761016081880312156116dd57600080fd5b6116e5611336565b6116ee826112a6565b81526116fc602083016112a6565b602082015261170d604083016112a6565b604082015261171f88606084016115cd565b60608201526117318860c08401611611565b6080820152611743610100830161164c565b60a082015261175561012083016114ae565b60c082015261176761014083016114ae565b60e08201528352602090920191610160016116c4565b5095945050505050565b803563ffffffff811681146112b157600080fd5b600060e082360312156117ad57600080fd5b6117b5611359565b6117be836112a6565b815260208301356001600160401b038111156117d957600080fd5b6117e5368286016113ab565b60208301525060408301356001600160401b0381111561180457600080fd5b611810368286016113ab565b60408301525060608301356001600160401b0381111561182f57600080fd5b61183b36828601611663565b60608301525061184d6080840161164c565b608082015261185e60a08401611787565b60a082015261186f60c084016114ae565b60c082015292915050565b60005b8381101561189557818101518382015260200161187d565b50506000910152565b600082516112cc81846020870161187a565b6000602082840312156118c257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156118f2576118f26118c9565b92915050565b6000815180845261191081602086016020860161187a565b601f01601f19169290920160200192915050565b6001600160a01b0384168152606060208201819052600090611948908301856118f8565b8281036040840152610fd781856118f8565b60018060a01b038516815283602082015260806040820152600061198160808301856118f8565b9050600283106119a157634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b6000602082840312156119c257600080fd5b815161126a816114a0565b6001600160a01b039586168152602081019490945260408401929092529092166060820152608081019190915260a00190565b600060208284031215611a1257600080fd5b815161126a81611271565b600082825180855260208501945060208160051b8301016020850160005b83811015611a6d57601f19858403018852611a578383516118f8565b6020988901989093509190910190600101611a3b565b50909695505050505050565b604081526000611a8c6040830185611a1d565b8281036020840152611a9e8185611a1d565b95945050505050565b87815260e060208201526000611ac060e08301896118f8565b60ff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b9a9950505050505050505050565b60208152600061126a60208301846118f8565b6001600160a01b0384168152606060208201819052600090611b3f908301856118f8565b9050826040830152949350505050565b600060018201611b6157611b616118c9565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611b8d57611b8d611b68565b500490565b818103818111156118f2576118f26118c9565b600082611bb457611bb4611b68565b500690565b60018060a01b038616815284602082015260a060408201526000611be060a08301866118f8565b8281036060840152611bf281866118f8565b9150508260808301529695505050505050565b87815260e060208201526000611c1e60e08301896118f8565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b6000604082016001600160801b03851683526040602084015280845180835260608501915060208601925060005b81811015611a6d5783516001600160a01b0316835260209384019390920191600101611c89565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b03169083015260608084015191821690830152610160820190506080830151611d05608084018215159052565b5060a0830151611d1960a084018215159052565b5060c0830151611d5860c084018264ffffffffff815116825264ffffffffff602082015116602083015264ffffffffff60408201511660408301525050565b5060e0929092015180516001600160a01b031661012083015260200151610140909101529056fe5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072a264697066735822122003333a52c72d7fd00bfc049716b8e9b315c6d7df7e1feb6b71816b75fc06b82264736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063ba9a91a51461003b578063d58041b714610062575b600080fd5b610050600080516020611d8083398151915281565b60405190815260200160405180910390f35b61007561007036600461122f565b610077565b005b60006100866020830183611289565b9050600061009a60e0840160c08501611289565b905060006100ae6040850160208601611289565b90506000806100e58584866100c960a08b0160808c01611289565b6100d76101008c018c6112b6565b6100e09061141a565b6101d7565b90925090506000610136868587868661010460808e0160608f01611289565b8d60a00160208101906101179190611289565b8e806101200190610128919061148a565b610131906114b9565b6105ad565b905060005b61014961014089018961153c565b90508110156101cd5760006101626101408a018a61153c565b838181106101725761017261158c565b905060200281019061018491906115a2565b61018d9061179b565b90506101c488878988888e60400160208101906101aa9190611289565b8f60e00160208101906101bd9190611289565b8a89610938565b5060010161013b565b5050505050505050565b60408051600481526024810182526020810180516001600160e01b0316633f0f816960e21b17905290516000918291829182916001600160a01b038b169161021e9161189e565b6000604051808303816000865af19150503d806000811461025b576040519150601f19603f3d011682016040523d82523d6000602084013e610260565b606091505b5091509150816102b65760405162461bcd60e51b815260206004820152601a60248201527f4661696c656420746f20676574206c617374546f704861744964000000000000604482015260640160405180910390fd5b60e0818060200190518101906102cc91906118b0565b6102d79060016118df565b901b9350336001600160a01b031663468721a78a60003389600001518a6020015160405160240161030a93929190611924565b60408051601f198184030181529181526020820180516001600160e01b0316631a64dfad60e01b1790525160e085901b6001600160e01b03191681526103589392919060009060040161195a565b6020604051808303816000875af1158015610377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039b91906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f906103de908a90600080516020611d808339815191529046908f908b906004016119cd565b6020604051808303816000875af11580156103fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104219190611a00565b60408051600180825281830190925291945060009190816020015b606081526020019060019003908161043c57505060408051600180825281830190925291925060009190602082015b606081526020019060019003908161046b579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b815250826000815181106104b6576104b661158c565b60200260200101819052506104ca86610996565b816000815181106104dd576104dd61158c565b6020026020010181905250336001600160a01b031663468721a7896000858560405160240161050d929190611a79565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b031916815261055b9392919060009060040161195a565b6020604051808303816000875af115801561057a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059e91906119b0565b50505050509550959350505050565b60405162460ea360e61b8152600481018690526000906001600160a01b038a1690631183a8c090602401602060405180830381865afa1580156105f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061891906118b0565b9050336001600160a01b031663468721a78a600089866000015160018b8c8a604001518b602001516040516024016106569796959493929190611aa7565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b03191681526106a49392919060009060040161195a565b6020604051808303816000875af11580156106c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e791906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f9061072a908a90600080516020611d808339815191529046908f9088906004016119cd565b6020604051808303816000875af1158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190611a00565b506000846001600160a01b031663f1ab873c85604051806020016040528060008152506040516024016107a09190611b08565b60408051601f19818403018152918152602080830180516001600160e01b031663a4f9edbf60e01b17905290516107f291600080516020611d8083398151915291899101918252602082015260400190565b60408051601f198184030181529082905280516020909101206001600160e01b031960e086901b16825261082a939291600401611b1b565b6020604051808303816000875af1158015610849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086d9190611a00565b604051602481018490526001600160a01b0382166044820152909150339063468721a7908c9060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b03191681526108e79392919060009060040161195a565b6020604051808303816000875af1158015610906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092a91906119b0565b505098975050505050505050565b600061094d8a86868a8a888860800151610a9e565b9050600061095e8b8585858b610c05565b905060006109788b8b8e8760800151886000015187610f37565b9050610988846060015182610fe1565b505050505050505050505050565b6060816000036109bd5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156109e757806109d181611b4f565b91506109e09050600a83611b7e565b91506109c1565b6000816001600160401b03811115610a0157610a016112d6565b6040519080825280601f01601f191660200182016040528015610a2b576020820181803683370190505b5090505b8415610a9657610a40600183611b92565b9150610a4d600a86611ba5565b610a589060306118df565b60f81b818381518110610a6d57610a6d61158c565b60200101906001600160f81b031916908160001a905350610a8f600a86611b7e565b9450610a2f565b949350505050565b60006001600160801b03821615610bf757866001600160a01b0316632f7fb7b6878a6001600160a01b0316631183a8c0876040518263ffffffff1660e01b8152600401610aed91815260200190565b602060405180830381865afa158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e91906118b0565b886000604051602001610b4b929190918252602082015260400190565b60408051601f198184030181528282526001600160801b0389166020840152910160408051601f19818403018152908290526001600160e01b031960e087901b168252610bad94939291600080516020611d8083398151915290600401611bb9565b6020604051808303816000875af1158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611a00565b9050610bfa565b50825b979650505050505050565b60405162460ea360e61b81526004810185905260009081906001600160a01b03881690631183a8c090602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7291906118b0565b9050336001600160a01b031663468721a78860008989602001518a60a001518a8a8d60c001518e60400151604051602401610cb39796959493929190611c05565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b0319168152610d019392919060009060040161195a565b6020604051808303816000875af1158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4491906119b0565b5060808501516001600160801b031615610e6f5760408051600180825281830190925260009160208083019080368337019050509050856000015181600081518110610d9257610d9261158c565b60200260200101906001600160a01b031690816001600160a01b031681525050336001600160a01b031663468721a7866000896080015185604051602401610ddb929190611c5b565b60408051601f198184030181529181526020820180516001600160e01b0316634a231cef60e01b1790525160e085901b6001600160e01b0319168152610e299392919060009060040161195a565b6020604051808303816000875af1158015610e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6c91906119b0565b50505b8451604051602481018390526001600160a01b039091166044820152339063468721a790899060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b0319168152610ee99392919060009060040161195a565b6020604051808303816000875af1158015610f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2c91906119b0565b509695505050505050565b60006001600160801b03841615610f4f575081610fd7565b604051638a54c52f60e01b81526001600160a01b03881690638a54c52f90610f91908990600080516020611d808339815191529046908b9089906004016119cd565b6020604051808303816000875af1158015610fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd49190611a00565b90505b9695505050505050565b60005b825181101561122a5760008382815181106110015761100161158c565b60200260200101519050336001600160a01b031663468721a78260400151600084600001518560a001516040516024016110599291906001600160a01b039290921682526001600160801b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526110a79392919060009060040161195a565b6020604051808303816000875af11580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea91906119b0565b50336001600160a01b031663468721a78260000151600060405180610100016040528086602001516001600160a01b03168152602001886001600160a01b031681526020018660a001516001600160801b0316815260200186604001516001600160a01b031681526020018660c00151151581526020018660e001511515815260200186606001518152602001866080015181525060405160240161118f9190611cb0565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526111dd9392919060009060040161195a565b6020604051808303816000875af11580156111fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122091906119b0565b5050600101610fe4565b505050565b60006020828403121561124157600080fd5b81356001600160401b0381111561125757600080fd5b8201610160818503121561126a57600080fd5b9392505050565b6001600160a01b038116811461128657600080fd5b50565b60006020828403121561129b57600080fd5b813561126a81611271565b80356112b181611271565b919050565b60008235603e198336030181126112cc57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561130e5761130e6112d6565b60405290565b604051606081016001600160401b038111828210171561130e5761130e6112d6565b60405161010081016001600160401b038111828210171561130e5761130e6112d6565b60405160e081016001600160401b038111828210171561130e5761130e6112d6565b604051601f8201601f191681016001600160401b03811182821017156113a3576113a36112d6565b604052919050565b600082601f8301126113bc57600080fd5b81356001600160401b038111156113d5576113d56112d6565b6113e8601f8201601f191660200161137b565b8181528460208386010111156113fd57600080fd5b816020850160208301376000918101602001919091529392505050565b60006040823603121561142c57600080fd5b6114346112ec565b82356001600160401b0381111561144a57600080fd5b611456368286016113ab565b82525060208301356001600160401b0381111561147257600080fd5b61147e368286016113ab565b60208301525092915050565b60008235605e198336030181126112cc57600080fd5b801515811461128657600080fd5b80356112b1816114a0565b6000606082360312156114cb57600080fd5b6114d3611314565b82356001600160401b038111156114e957600080fd5b6114f5368286016113ab565b82525060208301356001600160401b0381111561151157600080fd5b61151d368286016113ab565b6020830152506040830135611531816114a0565b604082015292915050565b6000808335601e1984360301811261155357600080fd5b8301803591506001600160401b0382111561156d57600080fd5b6020019150600581901b360382131561158557600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b6000823560de198336030181126112cc57600080fd5b803564ffffffffff811681146112b157600080fd5b6000606082840312156115df57600080fd5b6115e7611314565b90506115f2826115b8565b8152611600602083016115b8565b6020820152611531604083016115b8565b60006040828403121561162357600080fd5b61162b6112ec565b9050813561163881611271565b808252506020820135602082015292915050565b80356001600160801b03811681146112b157600080fd5b600082601f83011261167457600080fd5b81356001600160401b0381111561168d5761168d6112d6565b61169c60208260051b0161137b565b80828252602082019150602061016084028601019250858311156116bf57600080fd5b602085015b8381101561177d5761016081880312156116dd57600080fd5b6116e5611336565b6116ee826112a6565b81526116fc602083016112a6565b602082015261170d604083016112a6565b604082015261171f88606084016115cd565b60608201526117318860c08401611611565b6080820152611743610100830161164c565b60a082015261175561012083016114ae565b60c082015261176761014083016114ae565b60e08201528352602090920191610160016116c4565b5095945050505050565b803563ffffffff811681146112b157600080fd5b600060e082360312156117ad57600080fd5b6117b5611359565b6117be836112a6565b815260208301356001600160401b038111156117d957600080fd5b6117e5368286016113ab565b60208301525060408301356001600160401b0381111561180457600080fd5b611810368286016113ab565b60408301525060608301356001600160401b0381111561182f57600080fd5b61183b36828601611663565b60608301525061184d6080840161164c565b608082015261185e60a08401611787565b60a082015261186f60c084016114ae565b60c082015292915050565b60005b8381101561189557818101518382015260200161187d565b50506000910152565b600082516112cc81846020870161187a565b6000602082840312156118c257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156118f2576118f26118c9565b92915050565b6000815180845261191081602086016020860161187a565b601f01601f19169290920160200192915050565b6001600160a01b0384168152606060208201819052600090611948908301856118f8565b8281036040840152610fd781856118f8565b60018060a01b038516815283602082015260806040820152600061198160808301856118f8565b9050600283106119a157634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b6000602082840312156119c257600080fd5b815161126a816114a0565b6001600160a01b039586168152602081019490945260408401929092529092166060820152608081019190915260a00190565b600060208284031215611a1257600080fd5b815161126a81611271565b600082825180855260208501945060208160051b8301016020850160005b83811015611a6d57601f19858403018852611a578383516118f8565b6020988901989093509190910190600101611a3b565b50909695505050505050565b604081526000611a8c6040830185611a1d565b8281036020840152611a9e8185611a1d565b95945050505050565b87815260e060208201526000611ac060e08301896118f8565b60ff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b9a9950505050505050505050565b60208152600061126a60208301846118f8565b6001600160a01b0384168152606060208201819052600090611b3f908301856118f8565b9050826040830152949350505050565b600060018201611b6157611b616118c9565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611b8d57611b8d611b68565b500490565b818103818111156118f2576118f26118c9565b600082611bb457611bb4611b68565b500690565b60018060a01b038616815284602082015260a060408201526000611be060a08301866118f8565b8281036060840152611bf281866118f8565b9150508260808301529695505050505050565b87815260e060208201526000611c1e60e08301896118f8565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b6000604082016001600160801b03851683526040602084015280845180835260608501915060208601925060005b81811015611a6d5783516001600160a01b0316835260209384019390920191600101611c89565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b03169083015260608084015191821690830152610160820190506080830151611d05608084018215159052565b5060a0830151611d1960a084018215159052565b5060c0830151611d5860c084018264ffffffffff815116825264ffffffffff602082015116602083015264ffffffffff60408201511660408301525050565b5060e0929092015180516001600160a01b031661012083015260200151610140909101529056fe5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072a264697066735822122003333a52c72d7fd00bfc049716b8e9b315c6d7df7e1feb6b71816b75fc06b82264736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": { + "createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))": { + "details": "For each hat that is included, if the hat is: - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-` on the Sablier contract. - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat to the calling safe.This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/sepolia/DecentSablierStreamManagement.json b/deployments/sepolia/DecentSablierStreamManagement.json index 3779fae4..7bd98975 100644 --- a/deployments/sepolia/DecentSablierStreamManagement.json +++ b/deployments/sepolia/DecentSablierStreamManagement.json @@ -1,5 +1,5 @@ { - "address": "0x5874bf327bA5b78b2371b13eB414B66179591d34", + "address": "0x2Eef732Cc457f5B077BEf9588EDc18be6edFC894", "abi": [ { "inputs": [], @@ -61,28 +61,28 @@ "type": "function" } ], - "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", + "transactionHash": "0x331ae3c9104684a772d336704d341936efc0d71769b59fb0ec76a26e495e0dde", "receipt": { "to": null, - "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", - "contractAddress": "0x5874bf327bA5b78b2371b13eB414B66179591d34", - "transactionIndex": 72, - "gasUsed": "384441", + "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", + "contractAddress": "0x2Eef732Cc457f5B077BEf9588EDc18be6edFC894", + "transactionIndex": 38, + "gasUsed": "384429", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x2d90032ee5f61b968f6e38065b8dab930b88bb292edc0059448acc5e02903a4a", - "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", + "blockHash": "0x5c63ea0482ec8b79d399a038d98200e8925c41255c5631f76e48a79aeebbbdcf", + "transactionHash": "0x331ae3c9104684a772d336704d341936efc0d71769b59fb0ec76a26e495e0dde", "logs": [], - "blockNumber": 6850325, - "cumulativeGasUsed": "8716271", + "blockNumber": 6984775, + "cumulativeGasUsed": "4250856", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "4511b61209438ca20d2458493e70bb24", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "numDeployments": 2, + "solcInputHash": "7c4217108daa894b08d16e65df533416", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xbda4bb7894ad5fddd6bd6e98660e4fa78cef606bcf97ea0fee7f3903e74b2bfa\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea264697066735822122062f1800b2f8ec6394c722019479a413b6e548f845021582aa4d800ab37f1c23f64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea264697066735822122062f1800b2f8ec6394c722019479a413b6e548f845021582aa4d800ab37f1c23f64736f6c634300081c0033", "devdoc": { "kind": "dev", "methods": {}, diff --git a/deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json b/deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json new file mode 100644 index 00000000..bcfbe691 --- /dev/null +++ b/deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json @@ -0,0 +1,387 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" + }, + "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/core/Module.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" + }, + "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts/governance/utils/IVotes.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@prb/math/src/Common.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" + }, + "@prb/math/src/sd1x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd1x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/sd1x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" + }, + "@prb/math/src/sd1x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" + }, + "@prb/math/src/sd59x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" + }, + "@prb/math/src/sd59x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" + }, + "@prb/math/src/sd59x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" + }, + "@prb/math/src/sd59x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/sd59x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" + }, + "@prb/math/src/sd59x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" + }, + "@prb/math/src/UD2x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud2x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud2x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" + }, + "@prb/math/src/ud2x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" + }, + "@prb/math/src/ud2x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" + }, + "@prb/math/src/UD60x18.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" + }, + "@prb/math/src/ud60x18/Casting.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" + }, + "@prb/math/src/ud60x18/Constants.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" + }, + "@prb/math/src/ud60x18/Conversions.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" + }, + "@prb/math/src/ud60x18/Errors.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" + }, + "@prb/math/src/ud60x18/Helpers.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" + }, + "@prb/math/src/ud60x18/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" + }, + "@prb/math/src/ud60x18/ValueType.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" + }, + "contracts/DecentAutonomousAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {IHatsElectionsEligibility} from \"./interfaces/hats/modules/IHatsElectionsEligibility.sol\";\nimport {FactoryFriendly} from \"@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol\";\nimport {ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {IDecentAutonomousAdmin} from \"./interfaces/IDecentAutonomousAdmin.sol\";\n\ncontract DecentAutonomousAdmin is\n IDecentAutonomousAdmin,\n ERC165,\n FactoryFriendly\n{\n // //////////////////////////////////////////////////////////////\n // initializer\n // //////////////////////////////////////////////////////////////\n function setUp(bytes memory initializeParams) public override initializer {}\n\n // //////////////////////////////////////////////////////////////\n // Public Functions\n // //////////////////////////////////////////////////////////////\n function triggerStartNextTerm(TriggerStartArgs calldata args) public {\n if (\n args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId) ==\n false\n ) revert NotCurrentWearer();\n\n IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility(\n args.hatsProtocol.getHatEligibilityModule(args.hatId)\n );\n\n hatsElectionModule.startNextTerm();\n\n // This will burn the hat since wearer is no longer eligible\n args.hatsProtocol.checkHatWearerStatus(args.hatId, args.currentWearer);\n // This will mint the hat to the nominated wearer\n args.hatsProtocol.mintHat(args.hatId, args.nominatedWearer);\n }\n\n function supportsInterface(\n bytes4 interfaceId\n ) public view override returns (bool) {\n return\n interfaceId == type(IDecentAutonomousAdmin).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n}\n" + }, + "contracts/DecentHatsCreationModule.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {LockupLinear, Broker} from \"./interfaces/sablier/types/DataTypes.sol\";\nimport {IHatsModuleFactory} from \"./interfaces/hats/IHatsModuleFactory.sol\";\nimport {IHatsElectionsEligibility} from \"./interfaces/hats/modules/IHatsElectionsEligibility.sol\";\nimport {ModuleProxyFactory} from \"@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {DecentHatsUtils} from \"./DecentHatsUtils.sol\";\n\ncontract DecentHatsCreationModule is DecentHatsUtils {\n struct TopHatParams {\n string details;\n string imageURI;\n }\n\n struct AdminHatParams {\n string details;\n string imageURI;\n bool isMutable;\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n IERC6551Registry erc6551Registry;\n IHatsModuleFactory hatsModuleFactory;\n ModuleProxyFactory moduleProxyFactory;\n address keyValuePairs;\n address decentAutonomousAdminMasterCopy;\n address hatsAccountImplementation;\n address hatsElectionsEligibilityImplementation;\n TopHatParams topHat;\n AdminHatParams adminHat;\n HatParams[] hats;\n }\n\n /* /////////////////////////////////////////////////////////////////////////////\n EXTERNAL FUNCTIONS\n ///////////////////////////////////////////////////////////////////////////// */\n /**\n * @notice For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat\n * to the calling safe.\n *\n * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev For each hat that is included, if the hat is:\n * - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-`\n * on the Sablier contract.\n * - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the\n * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) external {\n IHats hatsProtocol = params.hatsProtocol;\n address hatsAccountImplementation = params.hatsAccountImplementation;\n IERC6551Registry erc6551Registry = params.erc6551Registry;\n\n // Create Top Hat\n (uint256 topHatId, address topHatAccount) = _processTopHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n params.keyValuePairs,\n params.topHat\n );\n\n // Create Admin Hat\n uint256 adminHatId = _processAdminHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n topHatId,\n topHatAccount,\n params.moduleProxyFactory,\n params.decentAutonomousAdminMasterCopy,\n params.adminHat\n );\n\n // Create Role Hats\n for (uint256 i = 0; i < params.hats.length; ) {\n HatParams memory hat = params.hats[i];\n _processHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n topHatId,\n topHatAccount,\n params.hatsModuleFactory,\n params.hatsElectionsEligibilityImplementation,\n adminHatId,\n hat\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /* /////////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n ///////////////////////////////////////////////////////////////////////////// */\n\n function _processTopHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n address keyValuePairs,\n TopHatParams memory topHat\n ) internal returns (uint256 topHatId, address topHatAccount) {\n // Call lastTopHatId() and properly decode the response\n (bool success, bytes memory data) = address(hatsProtocol).call(\n abi.encodeWithSignature(\"lastTopHatId()\")\n );\n require(success, \"Failed to get lastTopHatId\");\n topHatId = (abi.decode(data, (uint256)) + 1) << 224;\n\n IAvatar(msg.sender).execTransactionFromModule(\n // Mint top hat to the safe\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"mintTopHat(address,string,string)\",\n msg.sender,\n topHat.details,\n topHat.imageURI\n ),\n Enum.Operation.Call\n );\n\n // Create top hat account\n topHatAccount = erc6551Registry.createAccount(\n hatsAccountImplementation,\n SALT,\n block.chainid,\n address(hatsProtocol),\n topHatId\n );\n\n // Declare Top Hat ID to Safe via KeyValuePairs\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n IAvatar(msg.sender).execTransactionFromModule(\n keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function _processAdminHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n uint256 topHatId,\n address topHatAccount,\n ModuleProxyFactory moduleProxyFactory,\n address decentAutonomousAdminMasterCopy,\n AdminHatParams memory adminHat\n ) internal returns (uint256 adminHatId) {\n // Create Admin Hat\n adminHatId = hatsProtocol.getNextId(topHatId);\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"createHat(uint256,string,uint32,address,address,bool,string)\",\n topHatId,\n adminHat.details,\n 1, // only one Admin Hat\n topHatAccount,\n topHatAccount,\n adminHat.isMutable,\n adminHat.imageURI\n ),\n Enum.Operation.Call\n );\n\n // Create Admin Hat's ERC6551 Account\n erc6551Registry.createAccount(\n hatsAccountImplementation,\n SALT,\n block.chainid,\n address(hatsProtocol),\n adminHatId\n );\n\n // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat\n address autonomousAdminModule = moduleProxyFactory.deployModule(\n decentAutonomousAdminMasterCopy,\n abi.encodeWithSignature(\"setUp(bytes)\", bytes(\"\")),\n uint256(\n keccak256(\n abi.encodePacked(\n // for the salt, we'll concatenate our static salt with the id of the Admin Hat\n SALT,\n adminHatId\n )\n )\n )\n );\n\n // Mint Hat to the Decent Autonomous Admin Module\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"mintHat(uint256,address)\",\n adminHatId,\n autonomousAdminModule\n ),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/DecentHatsUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {LockupLinear, Broker} from \"./interfaces/sablier/types/DataTypes.sol\";\nimport {IHatsModuleFactory} from \"./interfaces/hats/IHatsModuleFactory.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\n\nabstract contract DecentHatsUtils {\n bytes32 public constant SALT =\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n address asset;\n LockupLinear.Timestamps timestamps;\n Broker broker;\n uint128 totalAmount;\n bool cancelable;\n bool transferable;\n }\n\n struct HatParams {\n address wearer;\n string details;\n string imageURI;\n SablierStreamParams[] sablierStreamsParams;\n uint128 termEndDateTs; // If 0, this is an untermed Hat\n uint32 maxSupply;\n bool isMutable;\n }\n\n function _processHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n uint256 topHatId,\n address topHatAccount,\n IHatsModuleFactory hatsModuleFactory,\n address hatsElectionsEligibilityImplementation,\n uint256 adminHatId,\n HatParams memory hat\n ) internal {\n // Create eligibility module if needed\n address eligibilityAddress = _createEligibilityModule(\n hatsProtocol,\n hatsModuleFactory,\n hatsElectionsEligibilityImplementation,\n topHatId,\n topHatAccount,\n adminHatId,\n hat.termEndDateTs\n );\n\n // Create and Mint the Role Hat\n uint256 hatId = _createAndMintHat(\n hatsProtocol,\n adminHatId,\n hat,\n eligibilityAddress,\n topHatAccount\n );\n\n // Get the stream recipient (based on termed or not)\n address streamRecipient = _setupStreamRecipient(\n erc6551Registry,\n hatsAccountImplementation,\n address(hatsProtocol),\n hat.termEndDateTs,\n hat.wearer,\n hatId\n );\n\n // Create streams\n _processSablierStreams(hat.sablierStreamsParams, streamRecipient);\n }\n\n function _createEligibilityModule(\n IHats hatsProtocol,\n IHatsModuleFactory hatsModuleFactory,\n address hatsElectionsEligibilityImplementation,\n uint256 topHatId,\n address topHatAccount,\n uint256 adminHatId,\n uint128 termEndDateTs\n ) private returns (address) {\n if (termEndDateTs != 0) {\n return\n hatsModuleFactory.createHatsModule(\n hatsElectionsEligibilityImplementation,\n hatsProtocol.getNextId(adminHatId),\n abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID]\n abi.encode(termEndDateTs),\n uint256(SALT)\n );\n }\n return topHatAccount;\n }\n\n function _createAndMintHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n HatParams memory hat,\n address eligibilityAddress,\n address topHatAccount\n ) private returns (uint256) {\n uint256 hatId = hatsProtocol.getNextId(adminHatId);\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"createHat(uint256,string,uint32,address,address,bool,string)\",\n adminHatId,\n hat.details,\n hat.maxSupply,\n eligibilityAddress,\n topHatAccount,\n hat.isMutable,\n hat.imageURI\n ),\n Enum.Operation.Call\n );\n\n // If the hat is termed, nominate the wearer as the eligible member\n if (hat.termEndDateTs != 0) {\n address[] memory nominatedWearers = new address[](1);\n nominatedWearers[0] = hat.wearer;\n\n IAvatar(msg.sender).execTransactionFromModule(\n eligibilityAddress,\n 0,\n abi.encodeWithSignature(\n \"elect(uint128,address[])\",\n hat.termEndDateTs,\n nominatedWearers\n ),\n Enum.Operation.Call\n );\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"mintHat(uint256,address)\",\n hatId,\n hat.wearer\n ),\n Enum.Operation.Call\n );\n return hatId;\n }\n\n // Exists to avoid stack too deep errors\n function _setupStreamRecipient(\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n address hatsProtocol,\n uint128 termEndDateTs,\n address wearer,\n uint256 hatId\n ) private returns (address) {\n // If the hat is termed, the wearer is the stream recipient\n if (termEndDateTs != 0) {\n return wearer;\n }\n\n // Otherwise, the Hat's smart account is the stream recipient\n return\n erc6551Registry.createAccount(\n hatsAccountImplementation,\n SALT,\n block.chainid,\n hatsProtocol,\n hatId\n );\n }\n\n function _processSablierStreams(\n SablierStreamParams[] memory streamParams,\n address streamRecipient\n ) private {\n for (uint256 i = 0; i < streamParams.length; ) {\n SablierStreamParams memory sablierStreamParams = streamParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierStreamParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n sablierStreamParams.sablier,\n sablierStreamParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierStreamParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n LockupLinear.CreateWithTimestamps({\n sender: sablierStreamParams.sender,\n recipient: streamRecipient,\n totalAmount: sablierStreamParams.totalAmount,\n asset: IERC20(sablierStreamParams.asset),\n cancelable: sablierStreamParams.cancelable,\n transferable: sablierStreamParams.transferable,\n timestamps: sablierStreamParams.timestamps,\n broker: sablierStreamParams.broker\n })\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n}\n" + }, + "contracts/DecentSablierStreamManagement.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" + }, + "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" + }, + "contracts/interfaces/hats/HatsErrors.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface HatsErrors {\n /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats\n /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree`\n error NotAdmin(address user, uint256 hatId);\n\n /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat\n error NotHatWearer();\n\n /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat\n error NotAdminOrWearer();\n\n /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached\n error AllHatsWorn(uint256 hatId);\n\n /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin\n error MaxLevelsReached();\n\n /// @notice Emitted when an attempted hat id has empty intermediate level(s)\n error InvalidHatId();\n\n /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat\n error AlreadyWearingHat(address wearer, uint256 hatId);\n\n /// @notice Emitted when attempting to mint a non-existant hat\n error HatDoesNotExist(uint256 hatId);\n\n /// @notice Emmitted when attempting to mint or transfer a hat that is not active\n error HatNotActive();\n\n /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer\n error NotEligible();\n\n /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module\n error NotHatsToggle();\n\n /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module\n error NotHatsEligibility();\n\n /// @notice Emitted when array arguments to a batch function have mismatching lengths\n error BatchArrayLengthMismatch();\n\n /// @notice Emitted when attempting to mutate or transfer an immutable hat\n error Immutable();\n\n /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply\n error NewMaxSupplyTooLow();\n\n /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin\n error CircularLinkage();\n\n /// @notice Emitted when attempting to link or relink a tophat to a separate tree\n error CrossTreeLinkage();\n\n /// @notice Emitted when attempting to link a tophat without a request\n error LinkageNotRequested();\n\n /// @notice Emitted when attempting to unlink a tophat that does not have a wearer\n /// @dev This ensures that unlinking never results in a bricked tophat\n error InvalidUnlink();\n\n /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address\n error ZeroAddress();\n\n /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters)\n /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI\n /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()`\n error StringTooLong();\n}\n" + }, + "contracts/interfaces/hats/HatsEvents.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface HatsEvents {\n /// @notice Emitted when a new hat is created\n /// @param id The id for the new hat\n /// @param details A description of the Hat\n /// @param maxSupply The total instances of the Hat that can be worn at once\n /// @param eligibility The address that can report on the Hat wearer's status\n /// @param toggle The address that can deactivate the Hat\n /// @param mutable_ Whether the hat's properties are changeable after creation\n /// @param imageURI The image uri for this hat and the fallback for its\n event HatCreated(\n uint256 id,\n string details,\n uint32 maxSupply,\n address eligibility,\n address toggle,\n bool mutable_,\n string imageURI\n );\n\n /// @notice Emitted when a hat wearer's standing is updated\n /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction\n /// @param hatId The id of the wearer's hat\n /// @param wearer The wearer's address\n /// @param wearerStanding Whether the wearer is in good standing for the hat\n event WearerStandingChanged(\n uint256 hatId,\n address wearer,\n bool wearerStanding\n );\n\n /// @notice Emitted when a hat's status is updated\n /// @param hatId The id of the hat\n /// @param newStatus Whether the hat is active\n event HatStatusChanged(uint256 hatId, bool newStatus);\n\n /// @notice Emitted when a hat's details are updated\n /// @param hatId The id of the hat\n /// @param newDetails The updated details\n event HatDetailsChanged(uint256 hatId, string newDetails);\n\n /// @notice Emitted when a hat's eligibility module is updated\n /// @param hatId The id of the hat\n /// @param newEligibility The updated eligibiliy module\n event HatEligibilityChanged(uint256 hatId, address newEligibility);\n\n /// @notice Emitted when a hat's toggle module is updated\n /// @param hatId The id of the hat\n /// @param newToggle The updated toggle module\n event HatToggleChanged(uint256 hatId, address newToggle);\n\n /// @notice Emitted when a hat's mutability is updated\n /// @param hatId The id of the hat\n event HatMutabilityChanged(uint256 hatId);\n\n /// @notice Emitted when a hat's maximum supply is updated\n /// @param hatId The id of the hat\n /// @param newMaxSupply The updated max supply\n event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply);\n\n /// @notice Emitted when a hat's image URI is updated\n /// @param hatId The id of the hat\n /// @param newImageURI The updated image URI\n event HatImageURIChanged(uint256 hatId, string newImageURI);\n\n /// @notice Emitted when a tophat linkage is requested by its admin\n /// @param domain The domain of the tree tophat to link\n /// @param newAdmin The tophat's would-be admin in the parent tree\n event TopHatLinkRequested(uint32 domain, uint256 newAdmin);\n\n /// @notice Emitted when a tophat is linked to a another tree\n /// @param domain The domain of the newly-linked tophat\n /// @param newAdmin The tophat's new admin in the parent tree\n event TopHatLinked(uint32 domain, uint256 newAdmin);\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\nimport \"./IHatsIdUtilities.sol\";\nimport \"./HatsErrors.sol\";\nimport \"./HatsEvents.sol\";\n\ninterface IHats is IHatsIdUtilities, HatsErrors, HatsEvents {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function batchCreateHats(\n uint256[] calldata _admins,\n string[] calldata _details,\n uint32[] calldata _maxSupplies,\n address[] memory _eligibilityModules,\n address[] memory _toggleModules,\n bool[] calldata _mutables,\n string[] calldata _imageURIs\n ) external returns (bool success);\n\n function getNextId(uint256 _admin) external view returns (uint256 nextId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function batchMintHats(\n uint256[] calldata _hatIds,\n address[] calldata _wearers\n ) external returns (bool success);\n\n function setHatStatus(\n uint256 _hatId,\n bool _newStatus\n ) external returns (bool toggled);\n\n function checkHatStatus(uint256 _hatId) external returns (bool toggled);\n\n function setHatWearerStatus(\n uint256 _hatId,\n address _wearer,\n bool _eligible,\n bool _standing\n ) external returns (bool updated);\n\n function checkHatWearerStatus(\n uint256 _hatId,\n address _wearer\n ) external returns (bool updated);\n\n function renounceHat(uint256 _hatId) external;\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n\n /*//////////////////////////////////////////////////////////////\n HATS ADMIN FUNCTIONS\n //////////////////////////////////////////////////////////////*/\n\n function makeHatImmutable(uint256 _hatId) external;\n\n function changeHatDetails(\n uint256 _hatId,\n string memory _newDetails\n ) external;\n\n function changeHatEligibility(\n uint256 _hatId,\n address _newEligibility\n ) external;\n\n function changeHatToggle(uint256 _hatId, address _newToggle) external;\n\n function changeHatImageURI(\n uint256 _hatId,\n string memory _newImageURI\n ) external;\n\n function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external;\n\n function requestLinkTopHatToTree(\n uint32 _topHatId,\n uint256 _newAdminHat\n ) external;\n\n function approveLinkTopHatToTree(\n uint32 _topHatId,\n uint256 _newAdminHat,\n address _eligibility,\n address _toggle,\n string calldata _details,\n string calldata _imageURI\n ) external;\n\n function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external;\n\n function relinkTopHatWithinTree(\n uint32 _topHatDomain,\n uint256 _newAdminHat,\n address _eligibility,\n address _toggle,\n string calldata _details,\n string calldata _imageURI\n ) external;\n\n /*//////////////////////////////////////////////////////////////\n VIEW FUNCTIONS\n //////////////////////////////////////////////////////////////*/\n\n function viewHat(\n uint256 _hatId\n )\n external\n view\n returns (\n string memory details,\n uint32 maxSupply,\n uint32 supply,\n address eligibility,\n address toggle,\n string memory imageURI,\n uint16 lastHatId,\n bool mutable_,\n bool active\n );\n\n function isWearerOfHat(\n address _user,\n uint256 _hatId\n ) external view returns (bool isWearer);\n\n function isAdminOfHat(\n address _user,\n uint256 _hatId\n ) external view returns (bool isAdmin);\n\n function isInGoodStanding(\n address _wearer,\n uint256 _hatId\n ) external view returns (bool standing);\n\n function isEligible(\n address _wearer,\n uint256 _hatId\n ) external view returns (bool eligible);\n\n function getHatEligibilityModule(\n uint256 _hatId\n ) external view returns (address eligibility);\n\n function getHatToggleModule(\n uint256 _hatId\n ) external view returns (address toggle);\n\n function getHatMaxSupply(\n uint256 _hatId\n ) external view returns (uint32 maxSupply);\n\n function hatSupply(uint256 _hatId) external view returns (uint32 supply);\n\n function getImageURIForHat(\n uint256 _hatId\n ) external view returns (string memory _uri);\n\n function balanceOf(\n address wearer,\n uint256 hatId\n ) external view returns (uint256 balance);\n\n function balanceOfBatch(\n address[] calldata _wearers,\n uint256[] calldata _hatIds\n ) external view returns (uint256[] memory);\n\n function uri(uint256 id) external view returns (string memory _uri);\n}\n" + }, + "contracts/interfaces/hats/IHatsIdUtilities.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHatsIdUtilities {\n function buildHatId(\n uint256 _admin,\n uint16 _newHat\n ) external pure returns (uint256 id);\n\n function getHatLevel(uint256 _hatId) external view returns (uint32 level);\n\n function getLocalHatLevel(\n uint256 _hatId\n ) external pure returns (uint32 level);\n\n function isTopHat(uint256 _hatId) external view returns (bool _topHat);\n\n function isLocalTopHat(\n uint256 _hatId\n ) external pure returns (bool _localTopHat);\n\n function isValidHatId(\n uint256 _hatId\n ) external view returns (bool validHatId);\n\n function getAdminAtLevel(\n uint256 _hatId,\n uint32 _level\n ) external view returns (uint256 admin);\n\n function getAdminAtLocalLevel(\n uint256 _hatId,\n uint32 _level\n ) external pure returns (uint256 admin);\n\n function getTopHatDomain(\n uint256 _hatId\n ) external view returns (uint32 domain);\n\n function getTippyTopHatDomain(\n uint32 _topHatDomain\n ) external view returns (uint32 domain);\n\n function noCircularLinkage(\n uint32 _topHatDomain,\n uint256 _linkedAdmin\n ) external view returns (bool notCircular);\n\n function sameTippyTopHatDomain(\n uint32 _topHatDomain,\n uint256 _newAdminHat\n ) external view returns (bool sameDomain);\n}\n" + }, + "contracts/interfaces/hats/IHatsModuleFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IHatsModuleFactory {\n error HatsModuleFactory_ModuleAlreadyDeployed(\n address implementation,\n uint256 hatId,\n bytes otherImmutableArgs,\n uint256 saltNonce\n );\n\n error BatchArrayLengthMismatch();\n\n event HatsModuleFactory_ModuleDeployed(\n address implementation,\n address instance,\n uint256 hatId,\n bytes otherImmutableArgs,\n bytes initData,\n uint256 saltNonce\n );\n\n function HATS() external view returns (address);\n\n function version() external view returns (string memory);\n\n function createHatsModule(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n bytes calldata _initData,\n uint256 _saltNonce\n ) external returns (address _instance);\n\n function batchCreateHatsModule(\n address[] calldata _implementations,\n uint256[] calldata _hatIds,\n bytes[] calldata _otherImmutableArgsArray,\n bytes[] calldata _initDataArray,\n uint256[] calldata _saltNonces\n ) external returns (bool success);\n\n function getHatsModuleAddress(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view returns (address);\n\n function deployed(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view returns (bool);\n}\n" + }, + "contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\ninterface IHatsElectionsEligibility {\n event ElectionOpened(uint128 nextTermEnd);\n event ElectionCompleted(uint128 termEnd, address[] winners);\n event NewTermStarted(uint128 termEnd);\n event Recalled(uint128 termEnd, address[] accounts);\n\n /// @notice Returns the first second after the current term ends.\n /// @dev Also serves as the id for the current term.\n function currentTermEnd() external view returns (uint128);\n\n /// @notice Returns the first second after the next term ends.\n /// @dev Also serves as the id for the next term.\n function nextTermEnd() external view returns (uint128);\n\n /// @notice Returns the election status (open or closed) for a given term end.\n /// @param termEnd The term end timestamp to query.\n function electionStatus(\n uint128 termEnd\n ) external view returns (bool isElectionOpen);\n\n /// @notice Returns whether a candidate was elected in a given term.\n /// @param termEnd The term end timestamp to query.\n /// @param candidate The address of the candidate.\n function electionResults(\n uint128 termEnd,\n address candidate\n ) external view returns (bool elected);\n\n /// @notice Returns the BALLOT_BOX_HAT constant.\n function BALLOT_BOX_HAT() external pure returns (uint256);\n\n /// @notice Returns the ADMIN_HAT constant.\n function ADMIN_HAT() external pure returns (uint256);\n\n /**\n * @notice Submit the results of an election for a specified term.\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\n * @param _termEnd The id of the term for which the election results are being submitted.\n * @param _winners The addresses of the winners of the election.\n */\n function elect(uint128 _termEnd, address[] calldata _winners) external;\n\n /**\n * @notice Submit the results of a recall election for a specified term.\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\n * @param _termEnd The id of the term for which the recall results are being submitted.\n * @param _recallees The addresses to be recalled.\n */\n function recall(uint128 _termEnd, address[] calldata _recallees) external;\n\n /**\n * @notice Set the next term and open the election for it.\n * @dev Only callable by the wearer(s) of the ADMIN_HAT.\n * @param _newTermEnd The id of the term that will be opened.\n */\n function setNextTerm(uint128 _newTermEnd) external;\n\n /**\n * @notice Start the next term, updating the current term.\n * @dev Can be called by anyone, but will revert if conditions are not met.\n */\n function startNextTerm() external;\n\n /**\n * @notice Determine the eligibility and standing of a wearer for a hat.\n * @param _wearer The address of the hat wearer.\n * @param _hatId The ID of the hat.\n * @return eligible True if the wearer is eligible for the hat.\n * @return standing True if the wearer is in good standing.\n */\n function getWearerStatus(\n address _wearer,\n uint256 _hatId\n ) external view returns (bool eligible, bool standing);\n}\n" + }, + "contracts/interfaces/IDecentAutonomousAdmin.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IHats} from \"./hats/IHats.sol\";\n\ninterface IDecentAutonomousAdmin {\n error NotCurrentWearer();\n struct TriggerStartArgs {\n address currentWearer;\n IHats hatsProtocol;\n uint256 hatId;\n address nominatedWearer;\n }\n\n function triggerStartNextTerm(TriggerStartArgs calldata args) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/IAdminable.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" + }, + "contracts/interfaces/sablier/IERC4096.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2Lockup.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {Lockup, LockupLinear} from \"./types/DataTypes.sol\";\nimport {ISablierV2Lockup} from \"./ISablierV2Lockup.sol\";\n\n/// @title ISablierV2LockupLinear\n/// @notice Creates and manages Lockup streams with a linear distribution function.\ninterface ISablierV2LockupLinear is ISablierV2Lockup {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when a stream is created.\n /// @param streamId The ID of the newly created stream.\n /// @param funder The address which funded the stream.\n /// @param sender The address distributing the assets, which will have the ability to cancel the stream.\n /// @param recipient The address receiving the assets.\n /// @param amounts Struct encapsulating (i) the deposit amount, and (ii) the broker fee amount, both denoted\n /// in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Boolean indicating whether the stream will be cancelable or not.\n /// @param transferable Boolean indicating whether the stream NFT is transferable or not.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker The address of the broker who has helped create the stream, e.g. a front-end website.\n event CreateLockupLinearStream(\n uint256 streamId,\n address funder,\n address indexed sender,\n address indexed recipient,\n Lockup.CreateAmounts amounts,\n IERC20 indexed asset,\n bool cancelable,\n bool transferable,\n LockupLinear.Timestamps timestamps,\n address broker\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the stream's cliff time, which is a Unix timestamp. A value of zero means there\n /// is no cliff.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getCliffTime(\n uint256 streamId\n ) external view returns (uint40 cliffTime);\n\n /// @notice Retrieves the full stream details.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n /// @return stream See the documentation in {DataTypes}.\n function getStream(\n uint256 streamId\n ) external view returns (LockupLinear.StreamLL memory stream);\n\n /// @notice Retrieves the stream's start, cliff and end timestamps.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n /// @return timestamps See the documentation in {DataTypes}.\n function getTimestamps(\n uint256 streamId\n ) external view returns (LockupLinear.Timestamps memory timestamps);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Creates a stream by setting the start time to `block.timestamp`, and the end time to\n /// the sum of `block.timestamp` and `params.durations.total`. The stream is funded by `msg.sender` and is wrapped\n /// in an ERC-721 NFT.\n ///\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\n ///\n /// Requirements:\n /// - All requirements in {createWithTimestamps} must be met for the calculated parameters.\n ///\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\n /// @return streamId The ID of the newly created stream.\n function createWithDurations(\n LockupLinear.CreateWithDurations calldata params\n ) external returns (uint256 streamId);\n\n /// @notice Creates a stream with the provided start time and end time. The stream is funded by `msg.sender` and is\n /// wrapped in an ERC-721 NFT.\n ///\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\n ///\n /// Notes:\n /// - A cliff time of zero means there is no cliff.\n /// - As long as the times are ordered, it is not an error for the start or the cliff time to be in the past.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `params.totalAmount` must be greater than zero.\n /// - If set, `params.broker.fee` must not be greater than `MAX_BROKER_FEE`.\n /// - `params.timestamps.start` must be greater than zero and less than `params.timestamps.end`.\n /// - If set, `params.timestamps.cliff` must be greater than `params.timestamps.start` and less than\n /// `params.timestamps.end`.\n /// - `params.timestamps.end` must be in the future.\n /// - `params.recipient` must not be the zero address.\n /// - `msg.sender` must have allowed this contract to spend at least `params.totalAmount` assets.\n ///\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\n /// @return streamId The ID of the newly created stream.\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" + }, + "contracts/interfaces/sablier/types/DataTypes.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" + }, + "contracts/mocks/ERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" + }, + "contracts/mocks/MockContract.sol": { + "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" + }, + "contracts/mocks/MockDecentHatsUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {DecentHatsUtils} from \"../DecentHatsUtils.sol\";\nimport {IHats} from \"../interfaces/hats/IHats.sol\";\nimport {IERC6551Registry} from \"../interfaces/IERC6551Registry.sol\";\nimport {IHatsModuleFactory} from \"../interfaces/hats/IHatsModuleFactory.sol\";\n\ncontract MockDecentHatsUtils is DecentHatsUtils {\n // Expose the internal _processHat function for testing\n function processHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n uint256 topHatId,\n address topHatAccount,\n IHatsModuleFactory hatsModuleFactory,\n address hatsElectionsEligibilityImplementation,\n uint256 adminHatId,\n HatParams memory hat\n ) external {\n _processHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n topHatId,\n topHatAccount,\n hatsModuleFactory,\n hatsElectionsEligibilityImplementation,\n adminHatId,\n hat\n );\n }\n}\n" + }, + "contracts/mocks/MockHatsElectionEligibility.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\nimport {IHatsElectionsEligibility} from \"../interfaces/hats/modules/IHatsElectionsEligibility.sol\";\n\ncontract MockHatsElectionsEligibility is IHatsElectionsEligibility {\n function currentTermEnd() external view returns (uint128) {}\n\n function nextTermEnd() external view returns (uint128) {}\n\n function electionStatus(\n uint128 termEnd\n ) external view returns (bool isElectionOpen) {}\n\n function electionResults(\n uint128 termEnd,\n address candidate\n ) external view returns (bool elected) {}\n\n function BALLOT_BOX_HAT() external pure returns (uint256) {}\n\n function ADMIN_HAT() external pure returns (uint256) {}\n\n function elect(uint128 _termEnd, address[] calldata _winners) external {}\n\n function recall(uint128 _termEnd, address[] calldata _recallees) external {}\n\n function setNextTerm(uint128 _newTermEnd) external {}\n\n function startNextTerm() external {}\n\n function getWearerStatus(\n address,\n uint256\n ) external pure returns (bool eligible, bool standing) {\n return (true, true);\n }\n}\n" + }, + "contracts/mocks/MockHatsModuleFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IHatsModuleFactory} from \"../interfaces/hats/IHatsModuleFactory.sol\";\nimport {MockHatsElectionsEligibility} from \"./MockHatsElectionEligibility.sol\";\n\ncontract MockHatsModuleFactory is IHatsModuleFactory {\n function createHatsModule(\n address,\n uint256,\n bytes calldata,\n bytes calldata,\n uint256\n ) external override returns (address _instance) {\n // Deploy a new instance of MockHatsElectionEligibility\n MockHatsElectionsEligibility newModule = new MockHatsElectionsEligibility();\n _instance = address(newModule);\n }\n\n function getHatsModuleAddress(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view returns (address) {}\n\n function HATS() external view override returns (address) {}\n\n function version() external view override returns (string memory) {}\n\n function batchCreateHatsModule(\n address[] calldata _implementations,\n uint256[] calldata _hatIds,\n bytes[] calldata _otherImmutableArgsArray,\n bytes[] calldata _initDataArray,\n uint256[] calldata _saltNonces\n ) external override returns (bool success) {}\n\n function deployed(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view override returns (bool) {}\n}\n" + }, + "contracts/mocks/MockLockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" + }, + "contracts/mocks/MockSablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.22;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {ISablierV2LockupLinear} from \"../interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {MockLockupLinear} from \"./MockLockupLinear.sol\";\n\ncontract MockSablierV2LockupLinear {\n mapping(uint256 => MockLockupLinear.Stream) public streams;\n uint256 public nextStreamId = 1;\n\n // Add this event declaration at the contract level\n event StreamCreated(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n uint128 totalAmount,\n address indexed asset,\n bool cancelable,\n bool transferable,\n uint40 startTime,\n uint40 cliffTime,\n uint40 endTime\n );\n\n function createWithTimestamps(\n MockLockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId) {\n require(\n params.asset.transferFrom(\n msg.sender,\n address(this),\n params.totalAmount\n ),\n \"Token transfer failed\"\n );\n\n streamId = nextStreamId++;\n streams[streamId] = MockLockupLinear.Stream({\n sender: params.sender,\n recipient: params.recipient,\n totalAmount: params.totalAmount,\n asset: address(params.asset),\n cancelable: params.cancelable,\n wasCanceled: false,\n transferable: params.transferable,\n startTime: params.timestamps.start,\n cliffTime: params.timestamps.cliff,\n endTime: params.timestamps.end\n });\n\n // Emit the StreamCreated event\n emit StreamCreated(\n streamId,\n params.sender,\n params.recipient,\n params.totalAmount,\n address(params.asset),\n params.cancelable,\n params.transferable,\n params.timestamps.start,\n params.timestamps.cliff,\n params.timestamps.end\n );\n\n return streamId;\n }\n\n function getStream(\n uint256 streamId\n ) external view returns (MockLockupLinear.Stream memory) {\n return streams[streamId];\n }\n\n function withdrawableAmountOf(\n uint256 streamId\n ) public view returns (uint128) {\n MockLockupLinear.Stream memory stream = streams[streamId];\n if (block.timestamp <= stream.startTime) {\n return 0;\n }\n if (block.timestamp >= stream.endTime) {\n return stream.totalAmount;\n }\n return\n uint128(\n (stream.totalAmount * (block.timestamp - stream.startTime)) /\n (stream.endTime - stream.startTime)\n );\n }\n\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount) {\n withdrawnAmount = withdrawableAmountOf(streamId);\n MockLockupLinear.Stream storage stream = streams[streamId];\n\n require(\n msg.sender == stream.recipient,\n \"Only recipient can call withdraw\"\n );\n require(\n withdrawnAmount <= withdrawableAmountOf(streamId),\n \"Insufficient withdrawable amount\"\n );\n\n stream.totalAmount -= withdrawnAmount;\n IERC20(stream.asset).transfer(to, withdrawnAmount);\n }\n\n function cancel(uint256 streamId) external {\n MockLockupLinear.Stream memory stream = streams[streamId];\n require(stream.cancelable, \"Stream is not cancelable\");\n require(msg.sender == stream.sender, \"Only sender can cancel\");\n\n uint128 withdrawableAmount = withdrawableAmountOf(streamId);\n uint128 refundAmount = stream.totalAmount - withdrawableAmount;\n\n streams[streamId].wasCanceled = true;\n\n if (withdrawableAmount > 0) {\n IERC20(stream.asset).transfer(stream.recipient, withdrawableAmount);\n }\n if (refundAmount > 0) {\n IERC20(stream.asset).transfer(stream.sender, refundAmount);\n }\n }\n\n function isCancelable(uint256 streamId) external view returns (bool) {\n return streams[streamId].cancelable;\n }\n\n /// @dev Retrieves the stream's status without performing a null check.\n function statusOf(\n uint256 streamId\n ) public view returns (MockLockupLinear.Status) {\n uint256 withdrawableAmount = withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return MockLockupLinear.Status.DEPLETED;\n } else if (streams[streamId].wasCanceled) {\n return MockLockupLinear.Status.CANCELED;\n }\n\n if (block.timestamp < streams[streamId].startTime) {\n return MockLockupLinear.Status.PENDING;\n }\n\n if (block.timestamp < streams[streamId].endTime) {\n return MockLockupLinear.Status.STREAMING;\n } else {\n return MockLockupLinear.Status.SETTLED;\n }\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/test/DecentHats_0_1_0.test.ts b/test/DecentHats_0_1_0.test.ts deleted file mode 100644 index 08a347ad..00000000 --- a/test/DecentHats_0_1_0.test.ts +++ /dev/null @@ -1,694 +0,0 @@ -import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; -import { expect } from 'chai'; -/* eslint-disable-next-line import/no-extraneous-dependencies */ -import { ethers } from 'ethers'; -import hre from 'hardhat'; -import { - GnosisSafeL2, - GnosisSafeL2__factory, - DecentHats_0_1_0__factory, - KeyValuePairs, - KeyValuePairs__factory, - MockHats__factory, - ERC6551Registry__factory, - MockHatsAccount__factory, - ERC6551Registry, - DecentHats_0_1_0, - MockHatsAccount, - MockHats, - MockSablierV2LockupLinear__factory, - MockSablierV2LockupLinear, - MockERC20__factory, - MockERC20, -} from '../typechain-types'; - -import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; -import { - executeSafeTransaction, - getHatAccount, - predictGnosisSafeAddress, - SALT, - topHatIdToHatId, -} from './helpers'; - -describe('DecentHats_0_1_0', () => { - let dao: SignerWithAddress; - - let mockHats: MockHats; - let mockHatsAddress: string; - - let keyValuePairs: KeyValuePairs; - let gnosisSafe: GnosisSafeL2; - - let decentHats: DecentHats_0_1_0; - let decentHatsAddress: string; - - let gnosisSafeAddress: string; - let erc6551Registry: ERC6551Registry; - - let mockHatsAccountImplementation: MockHatsAccount; - let mockHatsAccountImplementationAddress: string; - - let mockSablier: MockSablierV2LockupLinear; - let mockSablierAddress: string; - - let mockERC20: MockERC20; - let mockERC20Address: string; - - beforeEach(async () => { - const signers = await hre.ethers.getSigners(); - const [deployer] = signers; - [, dao] = signers; - - mockHats = await new MockHats__factory(deployer).deploy(); - mockHatsAddress = await mockHats.getAddress(); - keyValuePairs = await new KeyValuePairs__factory(deployer).deploy(); - erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); - mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); - mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); - decentHatsAddress = await decentHats.getAddress(); - - const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); - const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); - const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); - - const createGnosisSetupCalldata = GnosisSafeL2__factory.createInterface().encodeFunctionData( - 'setup', - [ - [dao.address], - 1, - hre.ethers.ZeroAddress, - hre.ethers.ZeroHash, - hre.ethers.ZeroAddress, - hre.ethers.ZeroAddress, - 0, - hre.ethers.ZeroAddress, - ], - ); - - const saltNum = BigInt(`0x${Buffer.from(hre.ethers.randomBytes(32)).toString('hex')}`); - - const predictedGnosisSafeAddress = await predictGnosisSafeAddress( - createGnosisSetupCalldata, - saltNum, - gnosisSafeL2SingletonAddress, - gnosisSafeProxyFactory, - ); - gnosisSafeAddress = predictedGnosisSafeAddress; - - await gnosisSafeProxyFactory.createProxyWithNonce( - gnosisSafeL2SingletonAddress, - createGnosisSetupCalldata, - saltNum, - ); - - gnosisSafe = GnosisSafeL2__factory.connect(predictedGnosisSafeAddress, deployer); - - // Deploy MockSablierV2LockupLinear - mockSablier = await new MockSablierV2LockupLinear__factory(deployer).deploy(); - mockSablierAddress = await mockSablier.getAddress(); - - mockERC20 = await new MockERC20__factory(deployer).deploy('MockERC20', 'MCK'); - mockERC20Address = await mockERC20.getAddress(); - - await mockERC20.mint(gnosisSafeAddress, ethers.parseEther('1000000')); - }); - - describe('DecentHats', () => { - let enableModuleTx: ethers.ContractTransactionResponse; - - beforeEach(async () => { - enableModuleTx = await executeSafeTransaction({ - safe: gnosisSafe, - to: gnosisSafeAddress, - transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData( - 'enableModule', - [decentHatsAddress], - ), - signers: [dao], - }); - }); - - describe('Enabled as a module', () => { - it('Emits an ExecutionSuccess event', async () => { - await expect(enableModuleTx).to.emit(gnosisSafe, 'ExecutionSuccess'); - }); - - it('Emits an EnabledModule event', async () => { - await expect(enableModuleTx) - .to.emit(gnosisSafe, 'EnabledModule') - .withArgs(decentHatsAddress); - }); - }); - - describe('Creating a new Top Hat and Tree', () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; - - let topHatId: bigint; - let adminHatId: bigint; - let roleHatIds: bigint[]; - - beforeEach(async () => { - topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); - adminHatId = await mockHats.getNextId(topHatId); - roleHatIds = [ - await mockHats.getNextId(adminHatId), - await mockHats.getNextIdOffset(adminHatId, 1), - ]; - - createAndDeclareTreeTx = await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ], - ), - signers: [dao], - }); - }); - - it('Emits an ExecutionSuccess event', async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); - }); - - it('Emits an ExecutionFromModuleSuccess event', async () => { - await expect(createAndDeclareTreeTx) - .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); - }); - - it('Emits some hatsTreeId ValueUpdated events', async () => { - await expect(createAndDeclareTreeTx) - .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); - }); - - describe('Multiple calls', () => { - let createAndDeclareTreeTx2: ethers.ContractTransactionResponse; - let newTopHatId: bigint; - - beforeEach(async () => { - newTopHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); - createAndDeclareTreeTx2 = await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], - }, - ], - ), - signers: [dao], - }); - }); - - it('Emits an ExecutionSuccess event', async () => { - await expect(createAndDeclareTreeTx2).to.emit(gnosisSafe, 'ExecutionSuccess'); - }); - - it('Emits an ExecutionFromModuleSuccess event', async () => { - await expect(createAndDeclareTreeTx2) - .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); - }); - - it('Leaves the Hats contract with a correct lastTopHatId', async () => { - expect(await mockHats.lastTopHatId()).to.equal(2n); - }); - - it('Creates Top Hats with different IDs', async () => { - await expect(createAndDeclareTreeTx2) - .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', newTopHatId.toString()); - }); - }); - - describe('Creating Hats Accounts', () => { - it('Generates the correct Addresses for the current Hats', async () => { - const allHatsIds = [topHatId, adminHatId, ...roleHatIds]; - - for (const hatId of allHatsIds) { - const hatAccount = await getHatAccount( - hatId, - erc6551Registry, - mockHatsAccountImplementationAddress, - mockHatsAddress, - ); - - expect(await hatAccount.tokenId()).eq(hatId); - expect(await hatAccount.tokenImplementation()).eq(mockHatsAddress); - } - }); - }); - }); - - describe('Creating a new Top Hat and Tree with Sablier Streams', () => { - let createAndDeclareTreeTx: ethers.ContractTransactionResponse; - let currentBlockTimestamp: number; - let topHatId: bigint; - - beforeEach(async () => { - topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); - currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - - createAndDeclareTreeTx = await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - ], - }, - ], - ), - signers: [dao], - }); - }); - - it('Emits an ExecutionSuccess event', async () => { - await expect(createAndDeclareTreeTx).to.emit(gnosisSafe, 'ExecutionSuccess'); - }); - - it('Emits an ExecutionFromModuleSuccess event', async () => { - await expect(createAndDeclareTreeTx) - .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); - }); - - it('Emits some hatsTreeId ValueUpdated events', async () => { - await expect(createAndDeclareTreeTx) - .to.emit(keyValuePairs, 'ValueUpdated') - .withArgs(gnosisSafeAddress, 'topHatId', topHatId.toString()); - }); - - it('Creates a Sablier stream for the hat with stream parameters', async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), - ); - expect(streamCreatedEvents.length).to.equal(1); - - const event = streamCreatedEvents[0]; - expect(event.args.sender).to.equal(gnosisSafeAddress); - expect(event.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event.args.totalAmount).to.equal(ethers.parseEther('100')); - }); - - it('Does not create a Sablier stream for hats without stream parameters', async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), - ); - expect(streamCreatedEvents.length).to.equal(1); // Only one stream should be created - }); - - it('Creates a Sablier stream with correct timestamps', async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), - ); - expect(streamCreatedEvents.length).to.equal(1); - - const streamId = streamCreatedEvents[0].args.streamId; - const stream = await mockSablier.getStream(streamId); - - expect(stream.startTime).to.equal(currentBlockTimestamp); - expect(stream.endTime).to.equal(currentBlockTimestamp + 2592000); - }); - }); - - describe('Creating a new Top Hat and Tree with Multiple Sablier Streams per Hat', () => { - let currentBlockTimestamp: number; - - beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - - await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [ - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('50'), - asset: mockERC20Address, - cancelable: false, - transferable: true, - timestamps: { - start: currentBlockTimestamp, - cliff: 0, // No cliff - end: currentBlockTimestamp + 1296000, // 15 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - ], - }, - ], - ), - signers: [dao], - }); - }); - - it('Creates multiple Sablier streams for a single hat', async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), - ); - expect(streamCreatedEvents.length).to.equal(2); - - const event1 = streamCreatedEvents[0]; - expect(event1.args.sender).to.equal(gnosisSafeAddress); - expect(event1.args.recipient).to.not.equal(ethers.ZeroAddress); - expect(event1.args.totalAmount).to.equal(ethers.parseEther('100')); - - const event2 = streamCreatedEvents[1]; - expect(event2.args.sender).to.equal(gnosisSafeAddress); - expect(event2.args.recipient).to.equal(event1.args.recipient); - expect(event2.args.totalAmount).to.equal(ethers.parseEther('50')); - }); - - it('Creates streams with correct parameters', async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), - ); - - const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); - expect(stream1.cancelable === true); - expect(stream1.transferable === false); - expect(stream1.endTime - stream1.startTime).to.equal(2592000); - - const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); - expect(stream2.cancelable === false); - expect(stream2.transferable === true); - expect(stream2.endTime - stream2.startTime).to.equal(1296000); - }); - - it('Creates streams with correct timestamps', async () => { - const streamCreatedEvents = await mockSablier.queryFilter( - mockSablier.filters.StreamCreated(), - ); - - const stream1 = await mockSablier.getStream(streamCreatedEvents[0].args.streamId); - expect(stream1.startTime).to.equal(currentBlockTimestamp); - expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); - - const stream2 = await mockSablier.getStream(streamCreatedEvents[1].args.streamId); - expect(stream2.startTime).to.equal(currentBlockTimestamp); - expect(stream2.endTime).to.equal(currentBlockTimestamp + 1296000); - }); - }); - - describe('Creating a new hat on existing Tree', () => { - let topHatAccount: MockHatsAccount; - let currentBlockTimestamp: number; - let topHatId: bigint; - let adminHatId: bigint; - let createNewHatData: { - safe: GnosisSafeL2; - to: string; - transactionData: string; - signers: SignerWithAddress[]; - }; - let transferTopHatData: { - safe: GnosisSafeL2; - to: string; - transactionData: string; - signers: SignerWithAddress[]; - }; - - beforeEach(async () => { - currentBlockTimestamp = (await hre.ethers.provider.getBlock('latest'))!.timestamp; - topHatId = topHatIdToHatId((await mockHats.lastTopHatId()) + 1n); - adminHatId = await mockHats.getNextId(topHatId); - - await executeSafeTransaction({ - safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - 'createAndDeclareTree', - [ - { - hatsProtocol: mockHatsAddress, - hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), - keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', - adminHat: { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], - }, - hats: [], - }, - ], - ), - signers: [dao], - }); - - topHatAccount = await getHatAccount( - topHatId, - erc6551Registry, - mockHatsAccountImplementationAddress, - mockHatsAddress, - ); - - createNewHatData = { - safe: gnosisSafe, - to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( - 'createRoleHat', - [ - mockHatsAddress, - adminHatId, - { - maxSupply: 1, - details: '', - imageURI: '', - isMutable: true, - wearer: await topHatAccount.getAddress(), // any non-zero address - sablierParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now - }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - }, - topHatId, - await topHatAccount.getAddress(), - await erc6551Registry.getAddress(), - mockHatsAccountImplementationAddress, - SALT, - ], - ), - signers: [dao], - }; - transferTopHatData = { - safe: gnosisSafe, - to: mockHatsAddress, - transactionData: MockHats__factory.createInterface().encodeFunctionData('transferHat', [ - topHatId, - gnosisSafeAddress, - decentHatsAddress, - ]), - signers: [dao], - }; - }); - - it('Reverts if the top hat is not transferred to the DecentHats module first', async () => { - await expect(executeSafeTransaction(createNewHatData)).to.be.reverted; - }); - - it('Emits an ExecutionSuccess event', async () => { - // First transfer the top hat to the Safe - await executeSafeTransaction(transferTopHatData); - await expect(executeSafeTransaction(createNewHatData)).to.emit( - gnosisSafe, - 'ExecutionSuccess', - ); - }); - - it('Emits an ExecutionFromModuleSuccess event', async () => { - // First transfer the top hat to the Safe - await executeSafeTransaction(transferTopHatData); - await expect(executeSafeTransaction(createNewHatData)) - .to.emit(gnosisSafe, 'ExecutionFromModuleSuccess') - .withArgs(decentHatsAddress); - }); - - it('Transfers the top hat back to the Safe', async () => { - // First transfer the top hat to the Safe - await executeSafeTransaction(transferTopHatData); - - const isModuleWearerOfTopHat = await mockHats.isWearerOfHat(decentHatsAddress, topHatId); - expect(isModuleWearerOfTopHat).to.equal(true); - - await executeSafeTransaction(createNewHatData); - - const isSafeWearerOfTopHat = await mockHats.isWearerOfHat(gnosisSafeAddress, topHatId); - expect(isSafeWearerOfTopHat).to.equal(true); - }); - - it('Actually creates the new hat', async () => { - // First transfer the top hat to the Safe - await executeSafeTransaction(transferTopHatData); - - const nextHatIdBeforeCreatingNewHats = await mockHats.getNextId(adminHatId); - - await executeSafeTransaction(createNewHatData); - - const nextHatIdAfterCreatingNewHats = await mockHats.getNextId(adminHatId); - expect(nextHatIdAfterCreatingNewHats).to.not.equal(nextHatIdBeforeCreatingNewHats); - }); - }); - }); -}); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/DecentSablierStreamManagement.test.ts index 71c5ef94..05e84acb 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/DecentSablierStreamManagement.test.ts @@ -4,8 +4,10 @@ import { expect } from 'chai'; import { ethers } from 'ethers'; import hre from 'hardhat'; import { - DecentHats_0_1_0, - DecentHats_0_1_0__factory, + DecentAutonomousAdmin, + DecentAutonomousAdmin__factory, + DecentHatsCreationModule, + DecentHatsCreationModule__factory, DecentSablierStreamManagement, DecentSablierStreamManagement__factory, ERC6551Registry, @@ -19,8 +21,14 @@ import { MockHats__factory, MockHatsAccount, MockHatsAccount__factory, + MockHatsElectionsEligibility, + MockHatsElectionsEligibility__factory, + MockHatsModuleFactory, + MockHatsModuleFactory__factory, MockSablierV2LockupLinear, MockSablierV2LockupLinear__factory, + ModuleProxyFactory, + ModuleProxyFactory__factory, } from '../typechain-types'; import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from './GlobalSafeDeployments.test'; @@ -38,7 +46,7 @@ describe('DecentSablierStreamManagement', () => { let mockHats: MockHats; let mockHatsAddress: string; - let decentHats: DecentHats_0_1_0; + let decentHats: DecentHatsCreationModule; let decentHatsAddress: string; let decentSablierManagement: DecentSablierStreamManagement; @@ -66,6 +74,10 @@ describe('DecentSablierStreamManagement', () => { const streamFundsMax = ethers.parseEther('100'); let roleHatId: bigint; + let mockHatsModuleFactory: MockHatsModuleFactory; + let moduleProxyFactory: ModuleProxyFactory; + let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; + let hatsElectionsEligibilityImplementation: MockHatsElectionsEligibility; beforeEach(async () => { const signers = await hre.ethers.getSigners(); @@ -78,9 +90,16 @@ describe('DecentSablierStreamManagement', () => { mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHats_0_1_0__factory(deployer).deploy(); + decentHats = await new DecentHatsCreationModule__factory(deployer).deploy(); decentHatsAddress = await decentHats.getAddress(); + mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); + moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + hatsElectionsEligibilityImplementation = await new MockHatsElectionsEligibility__factory( + deployer, + ).deploy(); + const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); const gnosisSafeL2SingletonAddress = await gnosisSafeL2Singleton.getAddress(); @@ -150,23 +169,27 @@ describe('DecentSablierStreamManagement', () => { createAndDeclareTreeWithRolesAndStreamsTx = await executeSafeTransaction({ safe: gnosisSafe, to: decentHatsAddress, - transactionData: DecentHats_0_1_0__factory.createInterface().encodeFunctionData( + transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ { hatsProtocol: mockHatsAddress, hatsAccountImplementation: mockHatsAccountImplementationAddress, - registry: await erc6551Registry.getAddress(), + hatsModuleFactory: await mockHatsModuleFactory.getAddress(), + moduleProxyFactory: await moduleProxyFactory.getAddress(), + decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + hatsElectionsEligibilityImplementation: + await hatsElectionsEligibilityImplementation.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), keyValuePairs: await keyValuePairs.getAddress(), - topHatDetails: '', - topHatImageURI: '', + topHat: { + details: '', + imageURI: '', + }, adminHat: { - maxSupply: 1, details: '', imageURI: '', isMutable: false, - wearer: ethers.ZeroAddress, - sablierParams: [], }, hats: [ { @@ -175,7 +198,8 @@ describe('DecentSablierStreamManagement', () => { imageURI: '', isMutable: false, wearer: dao.address, - sablierParams: [ + termEndDateTs: 0, + sablierStreamsParams: [ { sablier: mockSablierAddress, sender: gnosisSafeAddress, From c3c9a6b2814c2ddd319f527203aecfc4aedcda0f Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 13:38:28 -0400 Subject: [PATCH 181/206] Move new modules into a new modules directory and rename some contracts --- contracts/mocks/MockDecentHatsUtils.sol | 4 +-- .../DecentHatsCreationModule.sol | 16 ++++----- .../DecentHatsModuleUtils.sol} | 12 +++---- .../DecentSablierStreamManagementModule.sol} | 8 ++--- ...18_deploy_DecentSablierStreamManagement.ts | 2 +- .../DecentHatsCreationModule.test.ts | 6 ++-- .../DecentHatsModuleUtils.test.ts} | 34 +++++++++---------- .../DecentSablierStreamManagement.test.ts | 26 +++++++------- 8 files changed, 54 insertions(+), 54 deletions(-) rename contracts/{ => modules}/DecentHatsCreationModule.sol (93%) rename contracts/{DecentHatsUtils.sol => modules/DecentHatsModuleUtils.sol} (94%) rename contracts/{DecentSablierStreamManagement.sol => modules/DecentSablierStreamManagementModule.sol} (87%) rename test/{ => modules}/DecentHatsCreationModule.test.ts (99%) rename test/{DecentHatsUtils.test.ts => modules/DecentHatsModuleUtils.test.ts} (89%) rename test/{ => modules}/DecentSablierStreamManagement.test.ts (95%) diff --git a/contracts/mocks/MockDecentHatsUtils.sol b/contracts/mocks/MockDecentHatsUtils.sol index 7820eee9..4186e147 100644 --- a/contracts/mocks/MockDecentHatsUtils.sol +++ b/contracts/mocks/MockDecentHatsUtils.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {DecentHatsUtils} from "../DecentHatsUtils.sol"; +import {DecentHatsModuleUtils} from "../modules/DecentHatsModuleUtils.sol"; import {IHats} from "../interfaces/hats/IHats.sol"; import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; -contract MockDecentHatsUtils is DecentHatsUtils { +contract MockDecentHatsModuleUtils is DecentHatsModuleUtils { // Expose the internal _processHat function for testing function processHat( IHats hatsProtocol, diff --git a/contracts/DecentHatsCreationModule.sol b/contracts/modules/DecentHatsCreationModule.sol similarity index 93% rename from contracts/DecentHatsCreationModule.sol rename to contracts/modules/DecentHatsCreationModule.sol index 78b70e2e..62a3f36a 100644 --- a/contracts/DecentHatsCreationModule.sol +++ b/contracts/modules/DecentHatsCreationModule.sol @@ -5,16 +5,16 @@ import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/IHats.sol"; -import {LockupLinear, Broker} from "./interfaces/sablier/types/DataTypes.sol"; -import {IHatsModuleFactory} from "./interfaces/hats/IHatsModuleFactory.sol"; -import {IHatsElectionsEligibility} from "./interfaces/hats/modules/IHatsElectionsEligibility.sol"; +import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; +import {IHats} from "../interfaces/hats/IHats.sol"; +import {LockupLinear, Broker} from "../interfaces/sablier/types/DataTypes.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; +import {IHatsElectionsEligibility} from "../interfaces/hats/modules/IHatsElectionsEligibility.sol"; import {ModuleProxyFactory} from "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol"; -import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; -import {DecentHatsUtils} from "./DecentHatsUtils.sol"; +import {ISablierV2LockupLinear} from "../interfaces/sablier/ISablierV2LockupLinear.sol"; +import {DecentHatsModuleUtils} from "./DecentHatsModuleUtils.sol"; -contract DecentHatsCreationModule is DecentHatsUtils { +contract DecentHatsCreationModule is DecentHatsModuleUtils { struct TopHatParams { string details; string imageURI; diff --git a/contracts/DecentHatsUtils.sol b/contracts/modules/DecentHatsModuleUtils.sol similarity index 94% rename from contracts/DecentHatsUtils.sol rename to contracts/modules/DecentHatsModuleUtils.sol index 2efe4a67..b35a39f9 100644 --- a/contracts/DecentHatsUtils.sol +++ b/contracts/modules/DecentHatsModuleUtils.sol @@ -4,13 +4,13 @@ pragma solidity 0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/IHats.sol"; -import {LockupLinear, Broker} from "./interfaces/sablier/types/DataTypes.sol"; -import {IHatsModuleFactory} from "./interfaces/hats/IHatsModuleFactory.sol"; -import {ISablierV2LockupLinear} from "./interfaces/sablier/ISablierV2LockupLinear.sol"; +import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; +import {IHats} from "../interfaces/hats/IHats.sol"; +import {LockupLinear, Broker} from "../interfaces/sablier/types/DataTypes.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; +import {ISablierV2LockupLinear} from "../interfaces/sablier/ISablierV2LockupLinear.sol"; -abstract contract DecentHatsUtils { +abstract contract DecentHatsModuleUtils { bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; diff --git a/contracts/DecentSablierStreamManagement.sol b/contracts/modules/DecentSablierStreamManagementModule.sol similarity index 87% rename from contracts/DecentSablierStreamManagement.sol rename to contracts/modules/DecentSablierStreamManagementModule.sol index 688958bb..18b5f97b 100644 --- a/contracts/DecentSablierStreamManagement.sol +++ b/contracts/modules/DecentSablierStreamManagementModule.sol @@ -3,12 +3,10 @@ pragma solidity 0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; -import {ISablierV2Lockup} from "./interfaces/sablier/ISablierV2Lockup.sol"; -import {Lockup} from "./interfaces/sablier/types/DataTypes.sol"; - -contract DecentSablierStreamManagement { - string public constant NAME = "DecentSablierStreamManagement"; +import {ISablierV2Lockup} from "../interfaces/sablier/ISablierV2Lockup.sol"; +import {Lockup} from "../interfaces/sablier/types/DataTypes.sol"; +contract DecentSablierStreamManagementModule { function withdrawMaxFromStream( ISablierV2Lockup sablier, address recipientHatAccount, diff --git a/deploy/core/018_deploy_DecentSablierStreamManagement.ts b/deploy/core/018_deploy_DecentSablierStreamManagement.ts index 8e406ced..abb13f1d 100644 --- a/deploy/core/018_deploy_DecentSablierStreamManagement.ts +++ b/deploy/core/018_deploy_DecentSablierStreamManagement.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, 'DecentSablierStreamManagement'); + await deployNonUpgradeable(hre, 'DecentSablierStreamManagementModule'); }; export default func; diff --git a/test/DecentHatsCreationModule.test.ts b/test/modules/DecentHatsCreationModule.test.ts similarity index 99% rename from test/DecentHatsCreationModule.test.ts rename to test/modules/DecentHatsCreationModule.test.ts index ee07de64..2765bfcb 100644 --- a/test/DecentHatsCreationModule.test.ts +++ b/test/modules/DecentHatsCreationModule.test.ts @@ -27,15 +27,15 @@ import { MockHatsModuleFactory__factory, ModuleProxyFactory, ModuleProxyFactory__factory, -} from '../typechain-types'; +} from '../../typechain-types'; -import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from '../GlobalSafeDeployments.test'; import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress, topHatIdToHatId, -} from './helpers'; +} from '../helpers'; describe('DecentHatsCreationModule', () => { let dao: SignerWithAddress; diff --git a/test/DecentHatsUtils.test.ts b/test/modules/DecentHatsModuleUtils.test.ts similarity index 89% rename from test/DecentHatsUtils.test.ts rename to test/modules/DecentHatsModuleUtils.test.ts index e223d15e..7203ef2c 100644 --- a/test/DecentHatsUtils.test.ts +++ b/test/modules/DecentHatsModuleUtils.test.ts @@ -3,8 +3,8 @@ import { expect } from 'chai'; import hre from 'hardhat'; import { - MockDecentHatsUtils, - MockDecentHatsUtils__factory, + MockDecentHatsModuleUtils, + MockDecentHatsModuleUtils__factory, MockHats, MockHats__factory, ERC6551Registry, @@ -19,24 +19,24 @@ import { MockERC20__factory, GnosisSafeL2, GnosisSafeL2__factory, -} from '../typechain-types'; +} from '../../typechain-types'; -import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from '../GlobalSafeDeployments.test'; import { getHatAccount, topHatIdToHatId, predictGnosisSafeAddress, executeSafeTransaction, -} from './helpers'; +} from '../helpers'; -describe('DecentHatsUtils', () => { +describe('DecentHatsModuleUtils', () => { let deployer: SignerWithAddress; let safeSigner: SignerWithAddress; let wearer: SignerWithAddress; let mockHats: MockHats; - let mockDecentHatsUtils: MockDecentHatsUtils; + let mockDecentHatsModuleUtils: MockDecentHatsModuleUtils; let erc6551Registry: ERC6551Registry; let mockHatsAccount: MockHatsAccount; let mockHatsModuleFactory: MockHatsModuleFactory; @@ -56,7 +56,7 @@ describe('DecentHatsUtils', () => { // Deploy mock contracts mockHats = await new MockHats__factory(deployer).deploy(); - mockDecentHatsUtils = await new MockDecentHatsUtils__factory(deployer).deploy(); + mockDecentHatsModuleUtils = await new MockDecentHatsModuleUtils__factory(deployer).deploy(); erc6551Registry = await new ERC6551Registry__factory(deployer).deploy(); mockHatsAccount = await new MockHatsAccount__factory(deployer).deploy(); mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); @@ -154,7 +154,7 @@ describe('DecentHatsUtils', () => { safe: gnosisSafe, to: gnosisSafeAddress, transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData('enableModule', [ - await mockDecentHatsUtils.getAddress(), + await mockDecentHatsModuleUtils.getAddress(), ]), signers: [safeSigner], }); @@ -175,8 +175,8 @@ describe('DecentHatsUtils', () => { const roleHatId = await mockHats.getNextId(adminHatId); await executeSafeTransaction({ safe: gnosisSafe, - to: await mockDecentHatsUtils.getAddress(), - transactionData: MockDecentHatsUtils__factory.createInterface().encodeFunctionData( + to: await mockDecentHatsModuleUtils.getAddress(), + transactionData: MockDecentHatsModuleUtils__factory.createInterface().encodeFunctionData( 'processHat', [ await mockHats.getAddress(), @@ -217,8 +217,8 @@ describe('DecentHatsUtils', () => { const roleHatId = await mockHats.getNextId(adminHatId); await executeSafeTransaction({ safe: gnosisSafe, - to: await mockDecentHatsUtils.getAddress(), - transactionData: MockDecentHatsUtils__factory.createInterface().encodeFunctionData( + to: await mockDecentHatsModuleUtils.getAddress(), + transactionData: MockDecentHatsModuleUtils__factory.createInterface().encodeFunctionData( 'processHat', [ await mockHats.getAddress(), @@ -250,7 +250,7 @@ describe('DecentHatsUtils', () => { sablierStreamsParams: [ { sablier: await mockSablier.getAddress(), - sender: await mockDecentHatsUtils.getAddress(), + sender: await mockDecentHatsModuleUtils.getAddress(), asset: await mockERC20.getAddress(), timestamps: { start: currentBlockTimestamp, @@ -270,8 +270,8 @@ describe('DecentHatsUtils', () => { await executeSafeTransaction({ safe: gnosisSafe, - to: await mockDecentHatsUtils.getAddress(), - transactionData: MockDecentHatsUtils__factory.createInterface().encodeFunctionData( + to: await mockDecentHatsModuleUtils.getAddress(), + transactionData: MockDecentHatsModuleUtils__factory.createInterface().encodeFunctionData( 'processHat', [ await mockHats.getAddress(), @@ -298,7 +298,7 @@ describe('DecentHatsUtils', () => { expect(stream1.endTime).to.equal(currentBlockTimestamp + 2592000); const event = streamCreatedEvents[0]; - expect(event.args.sender).to.equal(await mockDecentHatsUtils.getAddress()); + expect(event.args.sender).to.equal(await mockDecentHatsModuleUtils.getAddress()); expect(event.args.totalAmount).to.equal(hre.ethers.parseEther('100')); }); }); diff --git a/test/DecentSablierStreamManagement.test.ts b/test/modules/DecentSablierStreamManagement.test.ts similarity index 95% rename from test/DecentSablierStreamManagement.test.ts rename to test/modules/DecentSablierStreamManagement.test.ts index 05e84acb..602d535a 100644 --- a/test/DecentSablierStreamManagement.test.ts +++ b/test/modules/DecentSablierStreamManagement.test.ts @@ -8,8 +8,8 @@ import { DecentAutonomousAdmin__factory, DecentHatsCreationModule, DecentHatsCreationModule__factory, - DecentSablierStreamManagement, - DecentSablierStreamManagement__factory, + DecentSablierStreamManagementModule, + DecentSablierStreamManagementModule__factory, ERC6551Registry, ERC6551Registry__factory, GnosisSafeL2, @@ -29,15 +29,15 @@ import { MockSablierV2LockupLinear__factory, ModuleProxyFactory, ModuleProxyFactory__factory, -} from '../typechain-types'; +} from '../../typechain-types'; -import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from './GlobalSafeDeployments.test'; +import { getGnosisSafeProxyFactory, getGnosisSafeL2Singleton } from '../GlobalSafeDeployments.test'; import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress, topHatIdToHatId, -} from './helpers'; +} from '../helpers'; describe('DecentSablierStreamManagement', () => { let dao: SignerWithAddress; @@ -49,7 +49,7 @@ describe('DecentSablierStreamManagement', () => { let decentHats: DecentHatsCreationModule; let decentHatsAddress: string; - let decentSablierManagement: DecentSablierStreamManagement; + let decentSablierManagement: DecentSablierStreamManagementModule; let decentSablierManagementAddress: string; let mockHatsAccountImplementation: MockHatsAccount; @@ -84,7 +84,9 @@ describe('DecentSablierStreamManagement', () => { const [deployer] = signers; [, dao] = signers; - decentSablierManagement = await new DecentSablierStreamManagement__factory(deployer).deploy(); + decentSablierManagement = await new DecentSablierStreamManagementModule__factory( + deployer, + ).deploy(); decentSablierManagementAddress = await decentSablierManagement.getAddress(); mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); @@ -283,7 +285,7 @@ describe('DecentSablierStreamManagement', () => { safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: - DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + DecentSablierStreamManagementModule__factory.createInterface().encodeFunctionData( 'withdrawMaxFromStream', [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address], ), @@ -341,7 +343,7 @@ describe('DecentSablierStreamManagement', () => { safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: - DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + DecentSablierStreamManagementModule__factory.createInterface().encodeFunctionData( 'withdrawMaxFromStream', [mockSablierAddress, await recipientHatAccount.getAddress(), streamId, dao.address], ), @@ -378,7 +380,7 @@ describe('DecentSablierStreamManagement', () => { safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: - DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + DecentSablierStreamManagementModule__factory.createInterface().encodeFunctionData( 'cancelStream', [mockSablierAddress, streamId], ), @@ -413,7 +415,7 @@ describe('DecentSablierStreamManagement', () => { safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: - DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + DecentSablierStreamManagementModule__factory.createInterface().encodeFunctionData( 'cancelStream', [mockSablierAddress, streamId], ), @@ -465,7 +467,7 @@ describe('DecentSablierStreamManagement', () => { safe: gnosisSafe, to: decentSablierManagementAddress, transactionData: - DecentSablierStreamManagement__factory.createInterface().encodeFunctionData( + DecentSablierStreamManagementModule__factory.createInterface().encodeFunctionData( 'cancelStream', [mockSablierAddress, streamId], ), From 861243a8c0a80c3b79c8fb862b2809b7946763dc Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 13:53:14 -0400 Subject: [PATCH 182/206] Add deployment script --- deploy/core/021_deploy_DecentHatsModificationModule.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 deploy/core/021_deploy_DecentHatsModificationModule.ts diff --git a/deploy/core/021_deploy_DecentHatsModificationModule.ts b/deploy/core/021_deploy_DecentHatsModificationModule.ts new file mode 100644 index 00000000..70c05c61 --- /dev/null +++ b/deploy/core/021_deploy_DecentHatsModificationModule.ts @@ -0,0 +1,9 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import { DeployFunction } from 'hardhat-deploy/types'; +import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; + +const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + await deployNonUpgradeable(hre, 'DecentHatsModificationModule'); +}; + +export default func; From 3630e9e53363c38e418054852f718bf2bdc095fb Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 13:57:09 -0400 Subject: [PATCH 183/206] Reorder some deployment scripts --- ...centAutonomousAdmin.ts => 017_deploy_DecentAutonomousAdmin.ts} | 0 ...tsCreationModule.ts => 018_deploy_DecentHatsCreationModule.ts} | 0 ...cationModule.ts => 019_deploy_DecentHatsModificationModule.ts} | 0 ...mManagement.ts => 020_deploy_DecentSablierStreamManagement.ts} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename deploy/core/{019_deploy_DecentAutonomousAdmin.ts => 017_deploy_DecentAutonomousAdmin.ts} (100%) rename deploy/core/{017_deploy_DecentHatsCreationModule.ts => 018_deploy_DecentHatsCreationModule.ts} (100%) rename deploy/core/{021_deploy_DecentHatsModificationModule.ts => 019_deploy_DecentHatsModificationModule.ts} (100%) rename deploy/core/{018_deploy_DecentSablierStreamManagement.ts => 020_deploy_DecentSablierStreamManagement.ts} (100%) diff --git a/deploy/core/019_deploy_DecentAutonomousAdmin.ts b/deploy/core/017_deploy_DecentAutonomousAdmin.ts similarity index 100% rename from deploy/core/019_deploy_DecentAutonomousAdmin.ts rename to deploy/core/017_deploy_DecentAutonomousAdmin.ts diff --git a/deploy/core/017_deploy_DecentHatsCreationModule.ts b/deploy/core/018_deploy_DecentHatsCreationModule.ts similarity index 100% rename from deploy/core/017_deploy_DecentHatsCreationModule.ts rename to deploy/core/018_deploy_DecentHatsCreationModule.ts diff --git a/deploy/core/021_deploy_DecentHatsModificationModule.ts b/deploy/core/019_deploy_DecentHatsModificationModule.ts similarity index 100% rename from deploy/core/021_deploy_DecentHatsModificationModule.ts rename to deploy/core/019_deploy_DecentHatsModificationModule.ts diff --git a/deploy/core/018_deploy_DecentSablierStreamManagement.ts b/deploy/core/020_deploy_DecentSablierStreamManagement.ts similarity index 100% rename from deploy/core/018_deploy_DecentSablierStreamManagement.ts rename to deploy/core/020_deploy_DecentSablierStreamManagement.ts From 395093adc2493f5d80d83cd57eb71b4dd9af860f Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 13:58:30 -0400 Subject: [PATCH 184/206] Move the ModificationModule and correctly import ModuleUtils --- .../{ => modules}/DecentHatsModificationModule.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) rename contracts/{ => modules}/DecentHatsModificationModule.sol (84%) diff --git a/contracts/DecentHatsModificationModule.sol b/contracts/modules/DecentHatsModificationModule.sol similarity index 84% rename from contracts/DecentHatsModificationModule.sol rename to contracts/modules/DecentHatsModificationModule.sol index c01e8d31..a7d78132 100644 --- a/contracts/DecentHatsModificationModule.sol +++ b/contracts/modules/DecentHatsModificationModule.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IERC6551Registry} from "./interfaces/IERC6551Registry.sol"; -import {IHats} from "./interfaces/hats/full/IHats.sol"; -import {IHatsModuleFactory} from "./interfaces/hats/full/IHatsModuleFactory.sol"; -import {DecentHatsUtils} from "./DecentHatsUtils.sol"; +import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; +import {IHats} from "../interfaces/hats/IHats.sol"; +import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; +import {DecentHatsModuleUtils} from "./DecentHatsModuleUtils.sol"; -contract DecentHatsModificationModule is DecentHatsUtils { +contract DecentHatsModificationModule is DecentHatsModuleUtils { struct CreateTermedOrUntermedRoleHatParams { IHats hatsProtocol; IERC6551Registry registry; From fd04b9d8af0e5bbfaea0c014c0925df8a44960ea Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 14:41:47 -0400 Subject: [PATCH 185/206] Clean up the DecentHats modules for consistency and efficiency --- contracts/mocks/MockDecentHatsUtils.sol | 27 +---- .../modules/DecentHatsCreationModule.sol | 55 ++++----- .../modules/DecentHatsModificationModule.sol | 33 +---- contracts/modules/DecentHatsModuleUtils.sol | 93 ++++++++------ test/modules/DecentHatsCreationModule.test.ts | 14 ++- .../DecentHatsModificationModule.test.ts | 113 +++++++++--------- test/modules/DecentHatsModuleUtils.test.ts | 69 ++++++----- .../DecentSablierStreamManagement.test.ts | 2 +- 8 files changed, 192 insertions(+), 214 deletions(-) rename test/{ => modules}/DecentHatsModificationModule.test.ts (82%) diff --git a/contracts/mocks/MockDecentHatsUtils.sol b/contracts/mocks/MockDecentHatsUtils.sol index 4186e147..30ae6861 100644 --- a/contracts/mocks/MockDecentHatsUtils.sol +++ b/contracts/mocks/MockDecentHatsUtils.sol @@ -2,33 +2,10 @@ pragma solidity 0.8.28; import {DecentHatsModuleUtils} from "../modules/DecentHatsModuleUtils.sol"; -import {IHats} from "../interfaces/hats/IHats.sol"; -import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; -import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; contract MockDecentHatsModuleUtils is DecentHatsModuleUtils { // Expose the internal _processHat function for testing - function processHat( - IHats hatsProtocol, - IERC6551Registry erc6551Registry, - address hatsAccountImplementation, - uint256 topHatId, - address topHatAccount, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionsEligibilityImplementation, - uint256 adminHatId, - HatParams memory hat - ) external { - _processHat( - hatsProtocol, - erc6551Registry, - hatsAccountImplementation, - topHatId, - topHatAccount, - hatsModuleFactory, - hatsElectionsEligibilityImplementation, - adminHatId, - hat - ); + function processRoleHats(CreateRoleHatsParams calldata params) external { + _processRoleHats(params); } } diff --git a/contracts/modules/DecentHatsCreationModule.sol b/contracts/modules/DecentHatsCreationModule.sol index 62a3f36a..ee4319f6 100644 --- a/contracts/modules/DecentHatsCreationModule.sol +++ b/contracts/modules/DecentHatsCreationModule.sol @@ -32,7 +32,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { IHatsModuleFactory hatsModuleFactory; ModuleProxyFactory moduleProxyFactory; address keyValuePairs; - address decentAutonomousAdminMasterCopy; + address decentAutonomousAdminImplementation; address hatsAccountImplementation; address hatsElectionsEligibilityImplementation; TopHatParams topHat; @@ -62,50 +62,41 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. */ function createAndDeclareTree(CreateTreeParams calldata params) external { - IHats hatsProtocol = params.hatsProtocol; - address hatsAccountImplementation = params.hatsAccountImplementation; - IERC6551Registry erc6551Registry = params.erc6551Registry; - // Create Top Hat (uint256 topHatId, address topHatAccount) = _processTopHat( - hatsProtocol, - erc6551Registry, - hatsAccountImplementation, + params.hatsProtocol, + params.erc6551Registry, + params.hatsAccountImplementation, params.keyValuePairs, params.topHat ); // Create Admin Hat uint256 adminHatId = _processAdminHat( - hatsProtocol, - erc6551Registry, - hatsAccountImplementation, + params.hatsProtocol, + params.erc6551Registry, + params.hatsAccountImplementation, topHatId, topHatAccount, params.moduleProxyFactory, - params.decentAutonomousAdminMasterCopy, + params.decentAutonomousAdminImplementation, params.adminHat ); // Create Role Hats - for (uint256 i = 0; i < params.hats.length; ) { - HatParams memory hat = params.hats[i]; - _processHat( - hatsProtocol, - erc6551Registry, - hatsAccountImplementation, - topHatId, - topHatAccount, - params.hatsModuleFactory, - params.hatsElectionsEligibilityImplementation, - adminHatId, - hat - ); - - unchecked { - ++i; - } - } + CreateRoleHatsParams memory roleHatParams = CreateRoleHatsParams({ + hatsProtocol: params.hatsProtocol, + erc6551Registry: params.erc6551Registry, + hatsAccountImplementation: params.hatsAccountImplementation, + topHatId: topHatId, + topHatAccount: topHatAccount, + hatsModuleFactory: params.hatsModuleFactory, + hatsElectionsEligibilityImplementation: params + .hatsElectionsEligibilityImplementation, + adminHatId: adminHatId, + hats: params.hats + }); + _processRoleHats(roleHatParams); } /* ///////////////////////////////////////////////////////////////////////////// @@ -172,7 +163,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { uint256 topHatId, address topHatAccount, ModuleProxyFactory moduleProxyFactory, - address decentAutonomousAdminMasterCopy, + address decentAutonomousAdminImplementation, AdminHatParams memory adminHat ) internal returns (uint256 adminHatId) { // Create Admin Hat @@ -204,7 +195,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat address autonomousAdminModule = moduleProxyFactory.deployModule( - decentAutonomousAdminMasterCopy, + decentAutonomousAdminImplementation, abi.encodeWithSignature("setUp(bytes)", bytes("")), uint256( keccak256( diff --git a/contracts/modules/DecentHatsModificationModule.sol b/contracts/modules/DecentHatsModificationModule.sol index a7d78132..4f350409 100644 --- a/contracts/modules/DecentHatsModificationModule.sol +++ b/contracts/modules/DecentHatsModificationModule.sol @@ -1,24 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IERC6551Registry} from "../interfaces/IERC6551Registry.sol"; -import {IHats} from "../interfaces/hats/IHats.sol"; -import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; import {DecentHatsModuleUtils} from "./DecentHatsModuleUtils.sol"; contract DecentHatsModificationModule is DecentHatsModuleUtils { - struct CreateTermedOrUntermedRoleHatParams { - IHats hatsProtocol; - IERC6551Registry registry; - address topHatAccount; - address hatsAccountImplementation; - uint256 adminHatId; - uint256 topHatId; - HatParams hat; - address hatsElectionsEligibilityImplementation; - IHatsModuleFactory hatsModuleFactory; - } - /** * @notice Creates a new termed or untermed role hat and any streams on it. * @@ -33,20 +18,12 @@ contract DecentHatsModificationModule is DecentHatsModuleUtils { * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order * to avoid a race condition where not more than one active proposal to create a new role can exist at a time. * See: https://github.com/decentdao/decent-interface/issues/2402 + * + * @param roleHatsParams An array of params for each role hat to be created. */ - function createRoleHat( - CreateTermedOrUntermedRoleHatParams calldata params + function createRoleHats( + CreateRoleHatsParams calldata roleHatsParams ) external { - _processHat( - params.hatsProtocol, - params.registry, - params.hatsAccountImplementation, - params.topHatId, - params.topHatAccount, - params.hatsModuleFactory, - params.hatsElectionsEligibilityImplementation, - params.adminHatId, - params.hat - ); + _processRoleHats(roleHatsParams); } } diff --git a/contracts/modules/DecentHatsModuleUtils.sol b/contracts/modules/DecentHatsModuleUtils.sol index b35a39f9..09720a76 100644 --- a/contracts/modules/DecentHatsModuleUtils.sol +++ b/contracts/modules/DecentHatsModuleUtils.sol @@ -35,49 +35,64 @@ abstract contract DecentHatsModuleUtils { bool isMutable; } - function _processHat( - IHats hatsProtocol, - IERC6551Registry erc6551Registry, - address hatsAccountImplementation, - uint256 topHatId, - address topHatAccount, - IHatsModuleFactory hatsModuleFactory, - address hatsElectionsEligibilityImplementation, - uint256 adminHatId, - HatParams memory hat + struct CreateRoleHatsParams { + IHats hatsProtocol; + IERC6551Registry erc6551Registry; + address hatsAccountImplementation; + uint256 topHatId; + address topHatAccount; + IHatsModuleFactory hatsModuleFactory; + address hatsElectionsEligibilityImplementation; + uint256 adminHatId; + HatParams[] hats; + } + + function _processRoleHats( + CreateRoleHatsParams memory roleHatsParams ) internal { - // Create eligibility module if needed - address eligibilityAddress = _createEligibilityModule( - hatsProtocol, - hatsModuleFactory, - hatsElectionsEligibilityImplementation, - topHatId, - topHatAccount, - adminHatId, - hat.termEndDateTs - ); + for (uint256 i = 0; i < roleHatsParams.hats.length; ) { + HatParams memory hatParams = roleHatsParams.hats[i]; + + // Create eligibility module if needed + address eligibilityAddress = _createEligibilityModule( + roleHatsParams.hatsProtocol, + roleHatsParams.hatsModuleFactory, + roleHatsParams.hatsElectionsEligibilityImplementation, + roleHatsParams.topHatId, + roleHatsParams.topHatAccount, + roleHatsParams.adminHatId, + hatParams.termEndDateTs + ); - // Create and Mint the Role Hat - uint256 hatId = _createAndMintHat( - hatsProtocol, - adminHatId, - hat, - eligibilityAddress, - topHatAccount - ); + // Create and Mint the Role Hat + uint256 hatId = _createAndMintHat( + roleHatsParams.hatsProtocol, + roleHatsParams.adminHatId, + hatParams, + eligibilityAddress, + roleHatsParams.topHatAccount + ); - // Get the stream recipient (based on termed or not) - address streamRecipient = _setupStreamRecipient( - erc6551Registry, - hatsAccountImplementation, - address(hatsProtocol), - hat.termEndDateTs, - hat.wearer, - hatId - ); + // Get the stream recipient (based on termed or not) + address streamRecipient = _setupStreamRecipient( + roleHatsParams.erc6551Registry, + roleHatsParams.hatsAccountImplementation, + address(roleHatsParams.hatsProtocol), + hatParams.termEndDateTs, + hatParams.wearer, + hatId + ); - // Create streams - _processSablierStreams(hat.sablierStreamsParams, streamRecipient); + // Create streams + _processSablierStreams( + hatParams.sablierStreamsParams, + streamRecipient + ); + + unchecked { + ++i; + } + } } function _createEligibilityModule( diff --git a/test/modules/DecentHatsCreationModule.test.ts b/test/modules/DecentHatsCreationModule.test.ts index 2765bfcb..2d3d7025 100644 --- a/test/modules/DecentHatsCreationModule.test.ts +++ b/test/modules/DecentHatsCreationModule.test.ts @@ -193,7 +193,8 @@ describe('DecentHatsCreationModule', () => { erc6551Registry: await erc6551Registry.getAddress(), hatsModuleFactory: mockHatsModuleFactoryAddress, moduleProxyFactory: await moduleProxyFactory.getAddress(), - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminImplementation: + await decentAutonomousAdminMasterCopy.getAddress(), hatsAccountImplementation: mockHatsAccountImplementationAddress, keyValuePairs: await keyValuePairs.getAddress(), hatsElectionsEligibilityImplementation: @@ -276,7 +277,7 @@ describe('DecentHatsCreationModule', () => { details: '', imageURI: '', }, - decentAutonomousAdminMasterCopy: + decentAutonomousAdminImplementation: await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { @@ -356,7 +357,8 @@ describe('DecentHatsCreationModule', () => { details: '', imageURI: '', }, - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminImplementation: + await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { details: '', @@ -434,7 +436,8 @@ describe('DecentHatsCreationModule', () => { details: '', imageURI: '', }, - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminImplementation: + await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { details: '', @@ -556,7 +559,8 @@ describe('DecentHatsCreationModule', () => { details: '', imageURI: '', }, - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminImplementation: + await decentAutonomousAdminMasterCopy.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), adminHat: { details: '', diff --git a/test/DecentHatsModificationModule.test.ts b/test/modules/DecentHatsModificationModule.test.ts similarity index 82% rename from test/DecentHatsModificationModule.test.ts rename to test/modules/DecentHatsModificationModule.test.ts index 2fc3c861..f601300e 100644 --- a/test/DecentHatsModificationModule.test.ts +++ b/test/modules/DecentHatsModificationModule.test.ts @@ -28,15 +28,15 @@ import { MockHatsModuleFactory__factory, MockHatsElectionsEligibility__factory, DecentHatsCreationModule, -} from '../typechain-types'; +} from '../../typechain-types'; -import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from './GlobalSafeDeployments.test'; +import { getGnosisSafeL2Singleton, getGnosisSafeProxyFactory } from '../GlobalSafeDeployments.test'; import { executeSafeTransaction, getHatAccount, predictGnosisSafeAddress, topHatIdToHatId, -} from './helpers'; +} from '../helpers'; describe('DecentHatsModificationModule', () => { let safe: SignerWithAddress; @@ -170,7 +170,8 @@ describe('DecentHatsModificationModule', () => { erc6551Registry: await erc6551Registry.getAddress(), hatsModuleFactory: mockHatsModuleFactoryAddress, moduleProxyFactory: await moduleProxyFactory.getAddress(), - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminImplementation: + await decentAutonomousAdminMasterCopy.getAddress(), hatsAccountImplementation: mockHatsAccountImplementationAddress, keyValuePairs: await keyValuePairs.getAddress(), hatsElectionsEligibilityImplementation: @@ -243,39 +244,41 @@ describe('DecentHatsModificationModule', () => { to: decentHatsModificationModuleAddress, transactionData: DecentHatsModificationModule__factory.createInterface().encodeFunctionData( - 'createRoleHat', + 'createRoleHats', [ { hatsProtocol: mockHatsAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), topHatAccount: await topHatAccount.getAddress(), hatsAccountImplementation: mockHatsAccountImplementationAddress, adminHatId, topHatId, - hat: { - wearer: await topHatAccount.getAddress(), // any non-zero address, - details: '', - imageURI: '', - sablierStreamsParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now + hats: [ + { + wearer: await topHatAccount.getAddress(), // any non-zero address, + details: '', + imageURI: '', + sablierStreamsParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - termEndDateTs: 0, - maxSupply: 1, - isMutable: true, - }, + ], + termEndDateTs: 0, + maxSupply: 1, + isMutable: true, + }, + ], hatsElectionsEligibilityImplementation: mockHatsElectionsEligibilityImplementationAddress, hatsModuleFactory: mockHatsModuleFactoryAddress, @@ -342,39 +345,41 @@ describe('DecentHatsModificationModule', () => { to: decentHatsModificationModuleAddress, transactionData: DecentHatsModificationModule__factory.createInterface().encodeFunctionData( - 'createRoleHat', + 'createRoleHats', [ { hatsProtocol: mockHatsAddress, - registry: await erc6551Registry.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), topHatAccount: await topHatAccount.getAddress(), hatsAccountImplementation: mockHatsAccountImplementationAddress, adminHatId, topHatId, - hat: { - wearer: await topHatAccount.getAddress(), // any non-zero address, - details: '', - imageURI: '', - sablierStreamsParams: [ - { - sablier: mockSablierAddress, - sender: gnosisSafeAddress, - totalAmount: ethers.parseEther('100'), - asset: mockERC20Address, - cancelable: true, - transferable: false, - timestamps: { - start: currentBlockTimestamp, - cliff: currentBlockTimestamp + 86400, // 1 day cliff - end: currentBlockTimestamp + 2592000, // 30 days from now + hats: [ + { + wearer: await topHatAccount.getAddress(), // any non-zero address, + details: '', + imageURI: '', + sablierStreamsParams: [ + { + sablier: mockSablierAddress, + sender: gnosisSafeAddress, + totalAmount: ethers.parseEther('100'), + asset: mockERC20Address, + cancelable: true, + transferable: false, + timestamps: { + start: currentBlockTimestamp, + cliff: currentBlockTimestamp + 86400, // 1 day cliff + end: currentBlockTimestamp + 2592000, // 30 days from now + }, + broker: { account: ethers.ZeroAddress, fee: 0 }, }, - broker: { account: ethers.ZeroAddress, fee: 0 }, - }, - ], - termEndDateTs: currentBlockTimestamp + 2592000, // 30 days from now - maxSupply: 1, - isMutable: true, - }, + ], + termEndDateTs: currentBlockTimestamp + 2592000, // 30 days from now + maxSupply: 1, + isMutable: true, + }, + ], hatsElectionsEligibilityImplementation: mockHatsElectionsEligibilityImplementationAddress, hatsModuleFactory: mockHatsModuleFactoryAddress, diff --git a/test/modules/DecentHatsModuleUtils.test.ts b/test/modules/DecentHatsModuleUtils.test.ts index 7203ef2c..9f7f4f2d 100644 --- a/test/modules/DecentHatsModuleUtils.test.ts +++ b/test/modules/DecentHatsModuleUtils.test.ts @@ -177,17 +177,20 @@ describe('DecentHatsModuleUtils', () => { safe: gnosisSafe, to: await mockDecentHatsModuleUtils.getAddress(), transactionData: MockDecentHatsModuleUtils__factory.createInterface().encodeFunctionData( - 'processHat', + 'processRoleHats', [ - await mockHats.getAddress(), - await erc6551Registry.getAddress(), - await mockHatsAccount.getAddress(), - topHatId, - topHatAccount, - await mockHatsModuleFactory.getAddress(), - mockHatsElectionsEligibilityImplementationAddress, - adminHatId, - hatParams, + { + hatsProtocol: await mockHats.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), + hatsAccountImplementation: await mockHatsAccount.getAddress(), + topHatId, + topHatAccount, + hatsModuleFactory: await mockHatsModuleFactory.getAddress(), + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, + adminHatId, + hats: [hatParams], + }, ], ), signers: [safeSigner], @@ -219,17 +222,20 @@ describe('DecentHatsModuleUtils', () => { safe: gnosisSafe, to: await mockDecentHatsModuleUtils.getAddress(), transactionData: MockDecentHatsModuleUtils__factory.createInterface().encodeFunctionData( - 'processHat', + 'processRoleHats', [ - await mockHats.getAddress(), - await erc6551Registry.getAddress(), - await mockHatsAccount.getAddress(), - topHatId, - topHatAccount, - await mockHatsModuleFactory.getAddress(), - mockHatsElectionsEligibilityImplementationAddress, - adminHatId, - hatParams, + { + hatsProtocol: await mockHats.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), + hatsAccountImplementation: await mockHatsAccount.getAddress(), + topHatId, + topHatAccount, + hatsModuleFactory: await mockHatsModuleFactory.getAddress(), + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, + adminHatId, + hats: [hatParams], + }, ], ), signers: [safeSigner], @@ -272,17 +278,20 @@ describe('DecentHatsModuleUtils', () => { safe: gnosisSafe, to: await mockDecentHatsModuleUtils.getAddress(), transactionData: MockDecentHatsModuleUtils__factory.createInterface().encodeFunctionData( - 'processHat', + 'processRoleHats', [ - await mockHats.getAddress(), - await erc6551Registry.getAddress(), - await mockHatsAccount.getAddress(), - topHatId, - topHatAccount, - await mockHatsModuleFactory.getAddress(), - mockHatsElectionsEligibilityImplementationAddress, - adminHatId, - hatParams, + { + hatsProtocol: await mockHats.getAddress(), + erc6551Registry: await erc6551Registry.getAddress(), + hatsAccountImplementation: await mockHatsAccount.getAddress(), + topHatId, + topHatAccount, + hatsModuleFactory: await mockHatsModuleFactory.getAddress(), + hatsElectionsEligibilityImplementation: + mockHatsElectionsEligibilityImplementationAddress, + adminHatId, + hats: [hatParams], + }, ], ), signers: [safeSigner], diff --git a/test/modules/DecentSablierStreamManagement.test.ts b/test/modules/DecentSablierStreamManagement.test.ts index 602d535a..4ad59aa0 100644 --- a/test/modules/DecentSablierStreamManagement.test.ts +++ b/test/modules/DecentSablierStreamManagement.test.ts @@ -179,7 +179,7 @@ describe('DecentSablierStreamManagement', () => { hatsAccountImplementation: mockHatsAccountImplementationAddress, hatsModuleFactory: await mockHatsModuleFactory.getAddress(), moduleProxyFactory: await moduleProxyFactory.getAddress(), - decentAutonomousAdminMasterCopy: await decentAutonomousAdminMasterCopy.getAddress(), + decentAutonomousAdminImplementation: await decentAutonomousAdminMasterCopy.getAddress(), hatsElectionsEligibilityImplementation: await hatsElectionsEligibilityImplementation.getAddress(), erc6551Registry: await erc6551Registry.getAddress(), From d9bd0043eaf2ff892e05963799922b93c1510ee3 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 14:55:12 -0400 Subject: [PATCH 186/206] Delete accidentally commited deployment artifacts --- .../sepolia/DecentAutonomousAdmin.json | 270 ------------ .../sepolia/DecentHatsCreationModule.json | 269 ------------ .../DecentSablierStreamManagement.json | 100 ----- .../7c4217108daa894b08d16e65df533416.json | 387 ------------------ 4 files changed, 1026 deletions(-) delete mode 100644 deployments/sepolia/DecentAutonomousAdmin.json delete mode 100644 deployments/sepolia/DecentHatsCreationModule.json delete mode 100644 deployments/sepolia/DecentSablierStreamManagement.json delete mode 100644 deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json diff --git a/deployments/sepolia/DecentAutonomousAdmin.json b/deployments/sepolia/DecentAutonomousAdmin.json deleted file mode 100644 index 93c44806..00000000 --- a/deployments/sepolia/DecentAutonomousAdmin.json +++ /dev/null @@ -1,270 +0,0 @@ -{ - "address": "0x80C7973189D32F145Ef683dCe2720F1bc75623aa", - "abi": [ - { - "inputs": [], - "name": "NotCurrentWearer", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" - }, - { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "initializeParams", - "type": "bytes" - } - ], - "name": "setUp", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "address", - "name": "currentWearer", - "type": "address" - }, - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "nominatedWearer", - "type": "address" - } - ], - "internalType": "struct IDecentAutonomousAdmin.TriggerStartArgs", - "name": "args", - "type": "tuple" - } - ], - "name": "triggerStartNextTerm", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x2d5d9cac8b4449a55d0cf35d8657039c23c9d065d8195b487e9b7e29d3918763", - "receipt": { - "to": null, - "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x80C7973189D32F145Ef683dCe2720F1bc75623aa", - "transactionIndex": 37, - "gasUsed": "498713", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xda8520b03cec2db8b93fb5375ae3c1d358bba7322d3c12eebdd97ff8077b3ed7", - "transactionHash": "0x2d5d9cac8b4449a55d0cf35d8657039c23c9d065d8195b487e9b7e29d3918763", - "logs": [], - "blockNumber": 6984776, - "cumulativeGasUsed": "5842656", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "7c4217108daa894b08d16e65df533416", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NotCurrentWearer\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initializeParams\",\"type\":\"bytes\"}],\"name\":\"setUp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"currentWearer\",\"type\":\"address\"},{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"nominatedWearer\",\"type\":\"address\"}],\"internalType\":\"struct IDecentAutonomousAdmin.TriggerStartArgs\",\"name\":\"args\",\"type\":\"tuple\"}],\"name\":\"triggerStartNextTerm\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"events\":{\"Initialized(uint8)\":{\"details\":\"Triggered when the contract has been initialized or reinitialized.\"}},\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentAutonomousAdmin.sol\":\"DecentAutonomousAdmin\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\n\\nabstract contract FactoryFriendly is OwnableUpgradeable {\\n function setUp(bytes memory initializeParams) public virtual;\\n}\\n\",\"keccak256\":\"0x96e61585b7340a901a54eb4c157ce28b630bff3d9d4597dfaac692128ea458c4\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing 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\":\"0x247c62047745915c0af6b955470a72d1696ebad4352d7d3011aef1a2463cd888\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\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. Equivalent to `reinitializer(1)`.\\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\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 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 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\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.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 *\\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \\\"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(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) 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 require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(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 require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason 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 // 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}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"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/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/DecentAutonomousAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {IHatsElectionsEligibility} from \\\"./interfaces/hats/modules/IHatsElectionsEligibility.sol\\\";\\nimport {FactoryFriendly} from \\\"@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol\\\";\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {IDecentAutonomousAdmin} from \\\"./interfaces/IDecentAutonomousAdmin.sol\\\";\\n\\ncontract DecentAutonomousAdmin is\\n IDecentAutonomousAdmin,\\n ERC165,\\n FactoryFriendly\\n{\\n // //////////////////////////////////////////////////////////////\\n // initializer\\n // //////////////////////////////////////////////////////////////\\n function setUp(bytes memory initializeParams) public override initializer {}\\n\\n // //////////////////////////////////////////////////////////////\\n // Public Functions\\n // //////////////////////////////////////////////////////////////\\n function triggerStartNextTerm(TriggerStartArgs calldata args) public {\\n if (\\n args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId) ==\\n false\\n ) revert NotCurrentWearer();\\n\\n IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility(\\n args.hatsProtocol.getHatEligibilityModule(args.hatId)\\n );\\n\\n hatsElectionModule.startNextTerm();\\n\\n // This will burn the hat since wearer is no longer eligible\\n args.hatsProtocol.checkHatWearerStatus(args.hatId, args.currentWearer);\\n // This will mint the hat to the nominated wearer\\n args.hatsProtocol.mintHat(args.hatId, args.nominatedWearer);\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view override returns (bool) {\\n return\\n interfaceId == type(IDecentAutonomousAdmin).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n}\\n\",\"keccak256\":\"0x6a3fbb0d5393cba9f921404603ace27457a7de32493744deb91fa09229664e4c\",\"license\":\"MIT\"},\"contracts/interfaces/IDecentAutonomousAdmin.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {IHats} from \\\"./hats/IHats.sol\\\";\\n\\ninterface IDecentAutonomousAdmin {\\n error NotCurrentWearer();\\n struct TriggerStartArgs {\\n address currentWearer;\\n IHats hatsProtocol;\\n uint256 hatId;\\n address nominatedWearer;\\n }\\n\\n function triggerStartNextTerm(TriggerStartArgs calldata args) external;\\n}\\n\",\"keccak256\":\"0x6c0165ad0aaa6c27c42f3ebd72b069b74e6ee0b05e1ac78deb4390e24fb074f4\",\"license\":\"MIT\"},\"contracts/interfaces/hats/HatsErrors.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsErrors {\\n /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats\\n /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree`\\n error NotAdmin(address user, uint256 hatId);\\n\\n /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat\\n error NotHatWearer();\\n\\n /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat\\n error NotAdminOrWearer();\\n\\n /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached\\n error AllHatsWorn(uint256 hatId);\\n\\n /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin\\n error MaxLevelsReached();\\n\\n /// @notice Emitted when an attempted hat id has empty intermediate level(s)\\n error InvalidHatId();\\n\\n /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat\\n error AlreadyWearingHat(address wearer, uint256 hatId);\\n\\n /// @notice Emitted when attempting to mint a non-existant hat\\n error HatDoesNotExist(uint256 hatId);\\n\\n /// @notice Emmitted when attempting to mint or transfer a hat that is not active\\n error HatNotActive();\\n\\n /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer\\n error NotEligible();\\n\\n /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module\\n error NotHatsToggle();\\n\\n /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module\\n error NotHatsEligibility();\\n\\n /// @notice Emitted when array arguments to a batch function have mismatching lengths\\n error BatchArrayLengthMismatch();\\n\\n /// @notice Emitted when attempting to mutate or transfer an immutable hat\\n error Immutable();\\n\\n /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply\\n error NewMaxSupplyTooLow();\\n\\n /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin\\n error CircularLinkage();\\n\\n /// @notice Emitted when attempting to link or relink a tophat to a separate tree\\n error CrossTreeLinkage();\\n\\n /// @notice Emitted when attempting to link a tophat without a request\\n error LinkageNotRequested();\\n\\n /// @notice Emitted when attempting to unlink a tophat that does not have a wearer\\n /// @dev This ensures that unlinking never results in a bricked tophat\\n error InvalidUnlink();\\n\\n /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address\\n error ZeroAddress();\\n\\n /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters)\\n /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI\\n /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()`\\n error StringTooLong();\\n}\\n\",\"keccak256\":\"0x81b0056b7bed86eabc07c0e4a9655c586ddb8e6c128320593669b76efd5a08de\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/HatsEvents.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsEvents {\\n /// @notice Emitted when a new hat is created\\n /// @param id The id for the new hat\\n /// @param details A description of the Hat\\n /// @param maxSupply The total instances of the Hat that can be worn at once\\n /// @param eligibility The address that can report on the Hat wearer's status\\n /// @param toggle The address that can deactivate the Hat\\n /// @param mutable_ Whether the hat's properties are changeable after creation\\n /// @param imageURI The image uri for this hat and the fallback for its\\n event HatCreated(\\n uint256 id,\\n string details,\\n uint32 maxSupply,\\n address eligibility,\\n address toggle,\\n bool mutable_,\\n string imageURI\\n );\\n\\n /// @notice Emitted when a hat wearer's standing is updated\\n /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction\\n /// @param hatId The id of the wearer's hat\\n /// @param wearer The wearer's address\\n /// @param wearerStanding Whether the wearer is in good standing for the hat\\n event WearerStandingChanged(\\n uint256 hatId,\\n address wearer,\\n bool wearerStanding\\n );\\n\\n /// @notice Emitted when a hat's status is updated\\n /// @param hatId The id of the hat\\n /// @param newStatus Whether the hat is active\\n event HatStatusChanged(uint256 hatId, bool newStatus);\\n\\n /// @notice Emitted when a hat's details are updated\\n /// @param hatId The id of the hat\\n /// @param newDetails The updated details\\n event HatDetailsChanged(uint256 hatId, string newDetails);\\n\\n /// @notice Emitted when a hat's eligibility module is updated\\n /// @param hatId The id of the hat\\n /// @param newEligibility The updated eligibiliy module\\n event HatEligibilityChanged(uint256 hatId, address newEligibility);\\n\\n /// @notice Emitted when a hat's toggle module is updated\\n /// @param hatId The id of the hat\\n /// @param newToggle The updated toggle module\\n event HatToggleChanged(uint256 hatId, address newToggle);\\n\\n /// @notice Emitted when a hat's mutability is updated\\n /// @param hatId The id of the hat\\n event HatMutabilityChanged(uint256 hatId);\\n\\n /// @notice Emitted when a hat's maximum supply is updated\\n /// @param hatId The id of the hat\\n /// @param newMaxSupply The updated max supply\\n event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply);\\n\\n /// @notice Emitted when a hat's image URI is updated\\n /// @param hatId The id of the hat\\n /// @param newImageURI The updated image URI\\n event HatImageURIChanged(uint256 hatId, string newImageURI);\\n\\n /// @notice Emitted when a tophat linkage is requested by its admin\\n /// @param domain The domain of the tree tophat to link\\n /// @param newAdmin The tophat's would-be admin in the parent tree\\n event TopHatLinkRequested(uint32 domain, uint256 newAdmin);\\n\\n /// @notice Emitted when a tophat is linked to a another tree\\n /// @param domain The domain of the newly-linked tophat\\n /// @param newAdmin The tophat's new admin in the parent tree\\n event TopHatLinked(uint32 domain, uint256 newAdmin);\\n}\\n\",\"keccak256\":\"0x53413397d15e1636c3cd7bd667656b79bc2886785403b824bcd4ed122667f2c6\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\nimport \\\"./IHatsIdUtilities.sol\\\";\\nimport \\\"./HatsErrors.sol\\\";\\nimport \\\"./HatsEvents.sol\\\";\\n\\ninterface IHats is IHatsIdUtilities, HatsErrors, HatsEvents {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function batchCreateHats(\\n uint256[] calldata _admins,\\n string[] calldata _details,\\n uint32[] calldata _maxSupplies,\\n address[] memory _eligibilityModules,\\n address[] memory _toggleModules,\\n bool[] calldata _mutables,\\n string[] calldata _imageURIs\\n ) external returns (bool success);\\n\\n function getNextId(uint256 _admin) external view returns (uint256 nextId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function batchMintHats(\\n uint256[] calldata _hatIds,\\n address[] calldata _wearers\\n ) external returns (bool success);\\n\\n function setHatStatus(\\n uint256 _hatId,\\n bool _newStatus\\n ) external returns (bool toggled);\\n\\n function checkHatStatus(uint256 _hatId) external returns (bool toggled);\\n\\n function setHatWearerStatus(\\n uint256 _hatId,\\n address _wearer,\\n bool _eligible,\\n bool _standing\\n ) external returns (bool updated);\\n\\n function checkHatWearerStatus(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool updated);\\n\\n function renounceHat(uint256 _hatId) external;\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n HATS ADMIN FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function makeHatImmutable(uint256 _hatId) external;\\n\\n function changeHatDetails(\\n uint256 _hatId,\\n string memory _newDetails\\n ) external;\\n\\n function changeHatEligibility(\\n uint256 _hatId,\\n address _newEligibility\\n ) external;\\n\\n function changeHatToggle(uint256 _hatId, address _newToggle) external;\\n\\n function changeHatImageURI(\\n uint256 _hatId,\\n string memory _newImageURI\\n ) external;\\n\\n function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external;\\n\\n function requestLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat\\n ) external;\\n\\n function approveLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external;\\n\\n function relinkTopHatWithinTree(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n VIEW FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function viewHat(\\n uint256 _hatId\\n )\\n external\\n view\\n returns (\\n string memory details,\\n uint32 maxSupply,\\n uint32 supply,\\n address eligibility,\\n address toggle,\\n string memory imageURI,\\n uint16 lastHatId,\\n bool mutable_,\\n bool active\\n );\\n\\n function isWearerOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isWearer);\\n\\n function isAdminOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isAdmin);\\n\\n function isInGoodStanding(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool standing);\\n\\n function isEligible(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible);\\n\\n function getHatEligibilityModule(\\n uint256 _hatId\\n ) external view returns (address eligibility);\\n\\n function getHatToggleModule(\\n uint256 _hatId\\n ) external view returns (address toggle);\\n\\n function getHatMaxSupply(\\n uint256 _hatId\\n ) external view returns (uint32 maxSupply);\\n\\n function hatSupply(uint256 _hatId) external view returns (uint32 supply);\\n\\n function getImageURIForHat(\\n uint256 _hatId\\n ) external view returns (string memory _uri);\\n\\n function balanceOf(\\n address wearer,\\n uint256 hatId\\n ) external view returns (uint256 balance);\\n\\n function balanceOfBatch(\\n address[] calldata _wearers,\\n uint256[] calldata _hatIds\\n ) external view returns (uint256[] memory);\\n\\n function uri(uint256 id) external view returns (string memory _uri);\\n}\\n\",\"keccak256\":\"0x2867004bddc5148fa1937f25c0403e5d9977583aaf50fdbdb74bd463f64f21c8\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHatsIdUtilities.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHatsIdUtilities {\\n function buildHatId(\\n uint256 _admin,\\n uint16 _newHat\\n ) external pure returns (uint256 id);\\n\\n function getHatLevel(uint256 _hatId) external view returns (uint32 level);\\n\\n function getLocalHatLevel(\\n uint256 _hatId\\n ) external pure returns (uint32 level);\\n\\n function isTopHat(uint256 _hatId) external view returns (bool _topHat);\\n\\n function isLocalTopHat(\\n uint256 _hatId\\n ) external pure returns (bool _localTopHat);\\n\\n function isValidHatId(\\n uint256 _hatId\\n ) external view returns (bool validHatId);\\n\\n function getAdminAtLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external view returns (uint256 admin);\\n\\n function getAdminAtLocalLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external pure returns (uint256 admin);\\n\\n function getTopHatDomain(\\n uint256 _hatId\\n ) external view returns (uint32 domain);\\n\\n function getTippyTopHatDomain(\\n uint32 _topHatDomain\\n ) external view returns (uint32 domain);\\n\\n function noCircularLinkage(\\n uint32 _topHatDomain,\\n uint256 _linkedAdmin\\n ) external view returns (bool notCircular);\\n\\n function sameTippyTopHatDomain(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat\\n ) external view returns (bool sameDomain);\\n}\\n\",\"keccak256\":\"0x007fcc07b20bf84bacad1f9a2ddf4e30e1a8be961e144b7bef8e98a51781aee9\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.13;\\n\\ninterface IHatsElectionsEligibility {\\n event ElectionOpened(uint128 nextTermEnd);\\n event ElectionCompleted(uint128 termEnd, address[] winners);\\n event NewTermStarted(uint128 termEnd);\\n event Recalled(uint128 termEnd, address[] accounts);\\n\\n /// @notice Returns the first second after the current term ends.\\n /// @dev Also serves as the id for the current term.\\n function currentTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the first second after the next term ends.\\n /// @dev Also serves as the id for the next term.\\n function nextTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the election status (open or closed) for a given term end.\\n /// @param termEnd The term end timestamp to query.\\n function electionStatus(\\n uint128 termEnd\\n ) external view returns (bool isElectionOpen);\\n\\n /// @notice Returns whether a candidate was elected in a given term.\\n /// @param termEnd The term end timestamp to query.\\n /// @param candidate The address of the candidate.\\n function electionResults(\\n uint128 termEnd,\\n address candidate\\n ) external view returns (bool elected);\\n\\n /// @notice Returns the BALLOT_BOX_HAT constant.\\n function BALLOT_BOX_HAT() external pure returns (uint256);\\n\\n /// @notice Returns the ADMIN_HAT constant.\\n function ADMIN_HAT() external pure returns (uint256);\\n\\n /**\\n * @notice Submit the results of an election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the election results are being submitted.\\n * @param _winners The addresses of the winners of the election.\\n */\\n function elect(uint128 _termEnd, address[] calldata _winners) external;\\n\\n /**\\n * @notice Submit the results of a recall election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the recall results are being submitted.\\n * @param _recallees The addresses to be recalled.\\n */\\n function recall(uint128 _termEnd, address[] calldata _recallees) external;\\n\\n /**\\n * @notice Set the next term and open the election for it.\\n * @dev Only callable by the wearer(s) of the ADMIN_HAT.\\n * @param _newTermEnd The id of the term that will be opened.\\n */\\n function setNextTerm(uint128 _newTermEnd) external;\\n\\n /**\\n * @notice Start the next term, updating the current term.\\n * @dev Can be called by anyone, but will revert if conditions are not met.\\n */\\n function startNextTerm() external;\\n\\n /**\\n * @notice Determine the eligibility and standing of a wearer for a hat.\\n * @param _wearer The address of the hat wearer.\\n * @param _hatId The ID of the hat.\\n * @return eligible True if the wearer is eligible for the hat.\\n * @return standing True if the wearer is in good standing.\\n */\\n function getWearerStatus(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible, bool standing);\\n}\\n\",\"keccak256\":\"0x74dfc5d538d866ddb8ee2ca1b569abf62e02d848c59f308adf6075ecff175c7d\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b5061080f8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c806301ffc9a7146100675780630ac4a8e81461008f578063715018a6146100a45780638da5cb5b146100ac578063a4f9edbf146100c7578063f2fde38b146100da575b600080fd5b61007a61007536600461064d565b6100ed565b60405190151581526020015b60405180910390f35b6100a261009d36600461067e565b610124565b005b6100a2610405565b6033546040516001600160a01b039091168152602001610086565b6100a26100d53660046106af565b610419565b6100a26100e836600461077d565b610528565b60006001600160e01b03198216630158951d60e31b148061011e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610134604082016020830161077d565b6001600160a01b0316634352409a61014f602084018461077d565b604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301528401356024820152604401602060405180830381865afa15801561019c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c0919061079a565b15156000036101e2576040516302aa5ad560e11b815260040160405180910390fd5b60006101f4604083016020840161077d565b6001600160a01b0316638c07607783604001356040518263ffffffff1660e01b815260040161022591815260200190565b602060405180830381865afa158015610242573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026691906107bc565b9050806001600160a01b0316637dcc80546040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102a357600080fd5b505af11580156102b7573d6000803e3d6000fd5b506102cc92505050604083016020840161077d565b6001600160a01b0316633fa9d54460408401356102ec602086018661077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035c919061079a565b5061036d604083016020840161077d565b6001600160a01b031663641f776e6040840135610390608086016060870161077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156103dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610400919061079a565b505050565b61040d6105a1565b61041760006105fb565b565b600054610100900460ff16158080156104395750600054600160ff909116105b806104535750303b158015610453575060005460ff166001145b6104bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156104de576000805461ff0019166101001790555b8015610524576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6105306105a1565b6001600160a01b0381166105955760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104b2565b61059e816105fb565b50565b6033546001600160a01b031633146104175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104b2565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561065f57600080fd5b81356001600160e01b03198116811461067757600080fd5b9392505050565b6000608082840312801561069157600080fd5b509092915050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156106c157600080fd5b813567ffffffffffffffff8111156106d857600080fd5b8201601f810184136106e957600080fd5b803567ffffffffffffffff81111561070357610703610699565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561073257610732610699565b60405281815282820160200186101561074a57600080fd5b81602084016020830137600091810160200191909152949350505050565b6001600160a01b038116811461059e57600080fd5b60006020828403121561078f57600080fd5b813561067781610768565b6000602082840312156107ac57600080fd5b8151801515811461067757600080fd5b6000602082840312156107ce57600080fd5b81516106778161076856fea26469706673582212203efa05c08e63f84221d377b68763b018336f724f765ab2f48bdef7fc96aa814b64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100625760003560e01c806301ffc9a7146100675780630ac4a8e81461008f578063715018a6146100a45780638da5cb5b146100ac578063a4f9edbf146100c7578063f2fde38b146100da575b600080fd5b61007a61007536600461064d565b6100ed565b60405190151581526020015b60405180910390f35b6100a261009d36600461067e565b610124565b005b6100a2610405565b6033546040516001600160a01b039091168152602001610086565b6100a26100d53660046106af565b610419565b6100a26100e836600461077d565b610528565b60006001600160e01b03198216630158951d60e31b148061011e57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610134604082016020830161077d565b6001600160a01b0316634352409a61014f602084018461077d565b604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301528401356024820152604401602060405180830381865afa15801561019c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101c0919061079a565b15156000036101e2576040516302aa5ad560e11b815260040160405180910390fd5b60006101f4604083016020840161077d565b6001600160a01b0316638c07607783604001356040518263ffffffff1660e01b815260040161022591815260200190565b602060405180830381865afa158015610242573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026691906107bc565b9050806001600160a01b0316637dcc80546040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156102a357600080fd5b505af11580156102b7573d6000803e3d6000fd5b506102cc92505050604083016020840161077d565b6001600160a01b0316633fa9d54460408401356102ec602086018661077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035c919061079a565b5061036d604083016020840161077d565b6001600160a01b031663641f776e6040840135610390608086016060870161077d565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156103dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610400919061079a565b505050565b61040d6105a1565b61041760006105fb565b565b600054610100900460ff16158080156104395750600054600160ff909116105b806104535750303b158015610453575060005460ff166001145b6104bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156104de576000805461ff0019166101001790555b8015610524576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b6105306105a1565b6001600160a01b0381166105955760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104b2565b61059e816105fb565b50565b6033546001600160a01b031633146104175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104b2565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006020828403121561065f57600080fd5b81356001600160e01b03198116811461067757600080fd5b9392505050565b6000608082840312801561069157600080fd5b509092915050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156106c157600080fd5b813567ffffffffffffffff8111156106d857600080fd5b8201601f810184136106e957600080fd5b803567ffffffffffffffff81111561070357610703610699565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561073257610732610699565b60405281815282820160200186101561074a57600080fd5b81602084016020830137600091810160200191909152949350505050565b6001600160a01b038116811461059e57600080fd5b60006020828403121561078f57600080fd5b813561067781610768565b6000602082840312156107ac57600080fd5b8151801515811461067757600080fd5b6000602082840312156107ce57600080fd5b81516106778161076856fea26469706673582212203efa05c08e63f84221d377b68763b018336f724f765ab2f48bdef7fc96aa814b64736f6c634300081c0033", - "devdoc": { - "events": { - "Initialized(uint8)": { - "details": "Triggered when the contract has been initialized or reinitialized." - } - }, - "kind": "dev", - "methods": { - "owner()": { - "details": "Returns the address of the current owner." - }, - "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." - }, - "supportsInterface(bytes4)": { - "details": "See {IERC165-supportsInterface}." - }, - "transferOwnership(address)": { - "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [ - { - "astId": 3585, - "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", - "label": "_initialized", - "offset": 0, - "slot": "0", - "type": "t_uint8" - }, - { - "astId": 3588, - "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", - "label": "_initializing", - "offset": 1, - "slot": "0", - "type": "t_bool" - }, - { - "astId": 6487, - "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", - "label": "__gap", - "offset": 0, - "slot": "1", - "type": "t_array(t_uint256)50_storage" - }, - { - "astId": 3379, - "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", - "label": "_owner", - "offset": 0, - "slot": "51", - "type": "t_address" - }, - { - "astId": 3499, - "contract": "contracts/DecentAutonomousAdmin.sol:DecentAutonomousAdmin", - "label": "__gap", - "offset": 0, - "slot": "52", - "type": "t_array(t_uint256)49_storage" - } - ], - "types": { - "t_address": { - "encoding": "inplace", - "label": "address", - "numberOfBytes": "20" - }, - "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_bool": { - "encoding": "inplace", - "label": "bool", - "numberOfBytes": "1" - }, - "t_uint256": { - "encoding": "inplace", - "label": "uint256", - "numberOfBytes": "32" - }, - "t_uint8": { - "encoding": "inplace", - "label": "uint8", - "numberOfBytes": "1" - } - } - } -} \ No newline at end of file diff --git a/deployments/sepolia/DecentHatsCreationModule.json b/deployments/sepolia/DecentHatsCreationModule.json deleted file mode 100644 index 66f4399d..00000000 --- a/deployments/sepolia/DecentHatsCreationModule.json +++ /dev/null @@ -1,269 +0,0 @@ -{ - "address": "0x7dF6463aC96e6dB04f5C1bCfed6B85e3dBB3736B", - "abi": [ - { - "inputs": [], - "name": "SALT", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "erc6551Registry", - "type": "address" - }, - { - "internalType": "contract IHatsModuleFactory", - "name": "hatsModuleFactory", - "type": "address" - }, - { - "internalType": "contract ModuleProxyFactory", - "name": "moduleProxyFactory", - "type": "address" - }, - { - "internalType": "address", - "name": "keyValuePairs", - "type": "address" - }, - { - "internalType": "address", - "name": "decentAutonomousAdminMasterCopy", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsElectionsEligibilityImplementation", - "type": "address" - }, - { - "components": [ - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - } - ], - "internalType": "struct DecentHatsCreationModule.TopHatParams", - "name": "topHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - } - ], - "internalType": "struct DecentHatsCreationModule.AdminHatParams", - "name": "adminHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "UD60x18", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct Broker", - "name": "broker", - "type": "tuple" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - } - ], - "internalType": "struct DecentHatsUtils.SablierStreamParams[]", - "name": "sablierStreamsParams", - "type": "tuple[]" - }, - { - "internalType": "uint128", - "name": "termEndDateTs", - "type": "uint128" - }, - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - } - ], - "internalType": "struct DecentHatsUtils.HatParams[]", - "name": "hats", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHatsCreationModule.CreateTreeParams", - "name": "params", - "type": "tuple" - } - ], - "name": "createAndDeclareTree", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xb1b5f1d6dd76730deb8a5bf5a3468fa6e64d7be5b6376306a50815641214a53c", - "receipt": { - "to": null, - "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x7dF6463aC96e6dB04f5C1bCfed6B85e3dBB3736B", - "transactionIndex": 64, - "gasUsed": "1702356", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xcec81ccef94d76b5c375ad27fa058a5f8336e4f97b970766ef88e30f4edc8e27", - "transactionHash": "0xb1b5f1d6dd76730deb8a5bf5a3468fa6e64d7be5b6376306a50815641214a53c", - "logs": [], - "blockNumber": 6984774, - "cumulativeGasUsed": "13380445", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "7c4217108daa894b08d16e65df533416", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"SALT\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"erc6551Registry\",\"type\":\"address\"},{\"internalType\":\"contract IHatsModuleFactory\",\"name\":\"hatsModuleFactory\",\"type\":\"address\"},{\"internalType\":\"contract ModuleProxyFactory\",\"name\":\"moduleProxyFactory\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"decentAutonomousAdminMasterCopy\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsElectionsEligibilityImplementation\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"}],\"internalType\":\"struct DecentHatsCreationModule.TopHatParams\",\"name\":\"topHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"}],\"internalType\":\"struct DecentHatsCreationModule.AdminHatParams\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"UD60x18\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct Broker\",\"name\":\"broker\",\"type\":\"tuple\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"}],\"internalType\":\"struct DecentHatsUtils.SablierStreamParams[]\",\"name\":\"sablierStreamsParams\",\"type\":\"tuple[]\"},{\"internalType\":\"uint128\",\"name\":\"termEndDateTs\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"}],\"internalType\":\"struct DecentHatsUtils.HatParams[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHatsCreationModule.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))\":{\"details\":\"For each hat that is included, if the hat is: - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-` on the Sablier contract. - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat to the calling safe.This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHatsCreationModule.sol\":\"DecentHatsCreationModule\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\ncontract ModuleProxyFactory {\\n event ModuleProxyCreation(\\n address indexed proxy,\\n address indexed masterCopy\\n );\\n\\n /// `target` can not be zero.\\n error ZeroAddress(address target);\\n\\n /// `address_` is already taken.\\n error TakenAddress(address address_);\\n\\n /// @notice Initialization failed.\\n error FailedInitialization();\\n\\n function createProxy(address target, bytes32 salt)\\n internal\\n returns (address result)\\n {\\n if (address(target) == address(0)) revert ZeroAddress(target);\\n bytes memory deployment = abi.encodePacked(\\n hex\\\"602d8060093d393df3363d3d373d3d3d363d73\\\",\\n target,\\n hex\\\"5af43d82803e903d91602b57fd5bf3\\\"\\n );\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\\n }\\n if (result == address(0)) revert TakenAddress(result);\\n }\\n\\n function deployModule(\\n address masterCopy,\\n bytes memory initializer,\\n uint256 saltNonce\\n ) public returns (address proxy) {\\n proxy = createProxy(\\n masterCopy,\\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\\n );\\n (bool success, ) = proxy.call(initializer);\\n if (!success) revert FailedInitialization();\\n\\n emit ModuleProxyCreation(proxy, masterCopy);\\n }\\n}\\n\",\"keccak256\":\"0x70f6f1d88cf3382748e58f85ba87279f5bb8761863c293dd8c197a71ff558761\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentHatsCreationModule.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {LockupLinear, Broker} from \\\"./interfaces/sablier/types/DataTypes.sol\\\";\\nimport {IHatsModuleFactory} from \\\"./interfaces/hats/IHatsModuleFactory.sol\\\";\\nimport {IHatsElectionsEligibility} from \\\"./interfaces/hats/modules/IHatsElectionsEligibility.sol\\\";\\nimport {ModuleProxyFactory} from \\\"@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {DecentHatsUtils} from \\\"./DecentHatsUtils.sol\\\";\\n\\ncontract DecentHatsCreationModule is DecentHatsUtils {\\n struct TopHatParams {\\n string details;\\n string imageURI;\\n }\\n\\n struct AdminHatParams {\\n string details;\\n string imageURI;\\n bool isMutable;\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n IERC6551Registry erc6551Registry;\\n IHatsModuleFactory hatsModuleFactory;\\n ModuleProxyFactory moduleProxyFactory;\\n address keyValuePairs;\\n address decentAutonomousAdminMasterCopy;\\n address hatsAccountImplementation;\\n address hatsElectionsEligibilityImplementation;\\n TopHatParams topHat;\\n AdminHatParams adminHat;\\n HatParams[] hats;\\n }\\n\\n /* /////////////////////////////////////////////////////////////////////////////\\n EXTERNAL FUNCTIONS\\n ///////////////////////////////////////////////////////////////////////////// */\\n /**\\n * @notice For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat\\n * to the calling safe.\\n *\\n * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev For each hat that is included, if the hat is:\\n * - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-`\\n * on the Sablier contract.\\n * - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the\\n * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) external {\\n IHats hatsProtocol = params.hatsProtocol;\\n address hatsAccountImplementation = params.hatsAccountImplementation;\\n IERC6551Registry erc6551Registry = params.erc6551Registry;\\n\\n // Create Top Hat\\n (uint256 topHatId, address topHatAccount) = _processTopHat(\\n hatsProtocol,\\n erc6551Registry,\\n hatsAccountImplementation,\\n params.keyValuePairs,\\n params.topHat\\n );\\n\\n // Create Admin Hat\\n uint256 adminHatId = _processAdminHat(\\n hatsProtocol,\\n erc6551Registry,\\n hatsAccountImplementation,\\n topHatId,\\n topHatAccount,\\n params.moduleProxyFactory,\\n params.decentAutonomousAdminMasterCopy,\\n params.adminHat\\n );\\n\\n // Create Role Hats\\n for (uint256 i = 0; i < params.hats.length; ) {\\n HatParams memory hat = params.hats[i];\\n _processHat(\\n hatsProtocol,\\n erc6551Registry,\\n hatsAccountImplementation,\\n topHatId,\\n topHatAccount,\\n params.hatsModuleFactory,\\n params.hatsElectionsEligibilityImplementation,\\n adminHatId,\\n hat\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /* /////////////////////////////////////////////////////////////////////////////\\n INTERNAL FUNCTIONS\\n ///////////////////////////////////////////////////////////////////////////// */\\n\\n function _processTopHat(\\n IHats hatsProtocol,\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n address keyValuePairs,\\n TopHatParams memory topHat\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n // Call lastTopHatId() and properly decode the response\\n (bool success, bytes memory data) = address(hatsProtocol).call(\\n abi.encodeWithSignature(\\\"lastTopHatId()\\\")\\n );\\n require(success, \\\"Failed to get lastTopHatId\\\");\\n topHatId = (abi.decode(data, (uint256)) + 1) << 224;\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n // Mint top hat to the safe\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"mintTopHat(address,string,string)\\\",\\n msg.sender,\\n topHat.details,\\n topHat.imageURI\\n ),\\n Enum.Operation.Call\\n );\\n\\n // Create top hat account\\n topHatAccount = erc6551Registry.createAccount(\\n hatsAccountImplementation,\\n SALT,\\n block.chainid,\\n address(hatsProtocol),\\n topHatId\\n );\\n\\n // Declare Top Hat ID to Safe via KeyValuePairs\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n IAvatar(msg.sender).execTransactionFromModule(\\n keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function _processAdminHat(\\n IHats hatsProtocol,\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n uint256 topHatId,\\n address topHatAccount,\\n ModuleProxyFactory moduleProxyFactory,\\n address decentAutonomousAdminMasterCopy,\\n AdminHatParams memory adminHat\\n ) internal returns (uint256 adminHatId) {\\n // Create Admin Hat\\n adminHatId = hatsProtocol.getNextId(topHatId);\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createHat(uint256,string,uint32,address,address,bool,string)\\\",\\n topHatId,\\n adminHat.details,\\n 1, // only one Admin Hat\\n topHatAccount,\\n topHatAccount,\\n adminHat.isMutable,\\n adminHat.imageURI\\n ),\\n Enum.Operation.Call\\n );\\n\\n // Create Admin Hat's ERC6551 Account\\n erc6551Registry.createAccount(\\n hatsAccountImplementation,\\n SALT,\\n block.chainid,\\n address(hatsProtocol),\\n adminHatId\\n );\\n\\n // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat\\n address autonomousAdminModule = moduleProxyFactory.deployModule(\\n decentAutonomousAdminMasterCopy,\\n abi.encodeWithSignature(\\\"setUp(bytes)\\\", bytes(\\\"\\\")),\\n uint256(\\n keccak256(\\n abi.encodePacked(\\n // for the salt, we'll concatenate our static salt with the id of the Admin Hat\\n SALT,\\n adminHatId\\n )\\n )\\n )\\n );\\n\\n // Mint Hat to the Decent Autonomous Admin Module\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"mintHat(uint256,address)\\\",\\n adminHatId,\\n autonomousAdminModule\\n ),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xa9750e9587839acd750d4df777e864389f3d2c138c27dbdc81b6a6a37d9cc61e\",\"license\":\"MIT\"},\"contracts/DecentHatsUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {LockupLinear, Broker} from \\\"./interfaces/sablier/types/DataTypes.sol\\\";\\nimport {IHatsModuleFactory} from \\\"./interfaces/hats/IHatsModuleFactory.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\n\\nabstract contract DecentHatsUtils {\\n bytes32 public constant SALT =\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n address asset;\\n LockupLinear.Timestamps timestamps;\\n Broker broker;\\n uint128 totalAmount;\\n bool cancelable;\\n bool transferable;\\n }\\n\\n struct HatParams {\\n address wearer;\\n string details;\\n string imageURI;\\n SablierStreamParams[] sablierStreamsParams;\\n uint128 termEndDateTs; // If 0, this is an untermed Hat\\n uint32 maxSupply;\\n bool isMutable;\\n }\\n\\n function _processHat(\\n IHats hatsProtocol,\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n uint256 topHatId,\\n address topHatAccount,\\n IHatsModuleFactory hatsModuleFactory,\\n address hatsElectionsEligibilityImplementation,\\n uint256 adminHatId,\\n HatParams memory hat\\n ) internal {\\n // Create eligibility module if needed\\n address eligibilityAddress = _createEligibilityModule(\\n hatsProtocol,\\n hatsModuleFactory,\\n hatsElectionsEligibilityImplementation,\\n topHatId,\\n topHatAccount,\\n adminHatId,\\n hat.termEndDateTs\\n );\\n\\n // Create and Mint the Role Hat\\n uint256 hatId = _createAndMintHat(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n eligibilityAddress,\\n topHatAccount\\n );\\n\\n // Get the stream recipient (based on termed or not)\\n address streamRecipient = _setupStreamRecipient(\\n erc6551Registry,\\n hatsAccountImplementation,\\n address(hatsProtocol),\\n hat.termEndDateTs,\\n hat.wearer,\\n hatId\\n );\\n\\n // Create streams\\n _processSablierStreams(hat.sablierStreamsParams, streamRecipient);\\n }\\n\\n function _createEligibilityModule(\\n IHats hatsProtocol,\\n IHatsModuleFactory hatsModuleFactory,\\n address hatsElectionsEligibilityImplementation,\\n uint256 topHatId,\\n address topHatAccount,\\n uint256 adminHatId,\\n uint128 termEndDateTs\\n ) private returns (address) {\\n if (termEndDateTs != 0) {\\n return\\n hatsModuleFactory.createHatsModule(\\n hatsElectionsEligibilityImplementation,\\n hatsProtocol.getNextId(adminHatId),\\n abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID]\\n abi.encode(termEndDateTs),\\n uint256(SALT)\\n );\\n }\\n return topHatAccount;\\n }\\n\\n function _createAndMintHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n HatParams memory hat,\\n address eligibilityAddress,\\n address topHatAccount\\n ) private returns (uint256) {\\n uint256 hatId = hatsProtocol.getNextId(adminHatId);\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createHat(uint256,string,uint32,address,address,bool,string)\\\",\\n adminHatId,\\n hat.details,\\n hat.maxSupply,\\n eligibilityAddress,\\n topHatAccount,\\n hat.isMutable,\\n hat.imageURI\\n ),\\n Enum.Operation.Call\\n );\\n\\n // If the hat is termed, nominate the wearer as the eligible member\\n if (hat.termEndDateTs != 0) {\\n address[] memory nominatedWearers = new address[](1);\\n nominatedWearers[0] = hat.wearer;\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n eligibilityAddress,\\n 0,\\n abi.encodeWithSignature(\\n \\\"elect(uint128,address[])\\\",\\n hat.termEndDateTs,\\n nominatedWearers\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(hatsProtocol),\\n 0,\\n abi.encodeWithSignature(\\n \\\"mintHat(uint256,address)\\\",\\n hatId,\\n hat.wearer\\n ),\\n Enum.Operation.Call\\n );\\n return hatId;\\n }\\n\\n // Exists to avoid stack too deep errors\\n function _setupStreamRecipient(\\n IERC6551Registry erc6551Registry,\\n address hatsAccountImplementation,\\n address hatsProtocol,\\n uint128 termEndDateTs,\\n address wearer,\\n uint256 hatId\\n ) private returns (address) {\\n // If the hat is termed, the wearer is the stream recipient\\n if (termEndDateTs != 0) {\\n return wearer;\\n }\\n\\n // Otherwise, the Hat's smart account is the stream recipient\\n return\\n erc6551Registry.createAccount(\\n hatsAccountImplementation,\\n SALT,\\n block.chainid,\\n hatsProtocol,\\n hatId\\n );\\n }\\n\\n function _processSablierStreams(\\n SablierStreamParams[] memory streamParams,\\n address streamRecipient\\n ) private {\\n for (uint256 i = 0; i < streamParams.length; ) {\\n SablierStreamParams memory sablierStreamParams = streamParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierStreamParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n sablierStreamParams.sablier,\\n sablierStreamParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierStreamParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n LockupLinear.CreateWithTimestamps({\\n sender: sablierStreamParams.sender,\\n recipient: streamRecipient,\\n totalAmount: sablierStreamParams.totalAmount,\\n asset: IERC20(sablierStreamParams.asset),\\n cancelable: sablierStreamParams.cancelable,\\n transferable: sablierStreamParams.transferable,\\n timestamps: sablierStreamParams.timestamps,\\n broker: sablierStreamParams.broker\\n })\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x098730a395481cb4b17996b677f284c3e83a631a1429a15aa98b793dd2879c19\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/HatsErrors.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsErrors {\\n /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats\\n /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree`\\n error NotAdmin(address user, uint256 hatId);\\n\\n /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat\\n error NotHatWearer();\\n\\n /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat\\n error NotAdminOrWearer();\\n\\n /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached\\n error AllHatsWorn(uint256 hatId);\\n\\n /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin\\n error MaxLevelsReached();\\n\\n /// @notice Emitted when an attempted hat id has empty intermediate level(s)\\n error InvalidHatId();\\n\\n /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat\\n error AlreadyWearingHat(address wearer, uint256 hatId);\\n\\n /// @notice Emitted when attempting to mint a non-existant hat\\n error HatDoesNotExist(uint256 hatId);\\n\\n /// @notice Emmitted when attempting to mint or transfer a hat that is not active\\n error HatNotActive();\\n\\n /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer\\n error NotEligible();\\n\\n /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module\\n error NotHatsToggle();\\n\\n /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module\\n error NotHatsEligibility();\\n\\n /// @notice Emitted when array arguments to a batch function have mismatching lengths\\n error BatchArrayLengthMismatch();\\n\\n /// @notice Emitted when attempting to mutate or transfer an immutable hat\\n error Immutable();\\n\\n /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply\\n error NewMaxSupplyTooLow();\\n\\n /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin\\n error CircularLinkage();\\n\\n /// @notice Emitted when attempting to link or relink a tophat to a separate tree\\n error CrossTreeLinkage();\\n\\n /// @notice Emitted when attempting to link a tophat without a request\\n error LinkageNotRequested();\\n\\n /// @notice Emitted when attempting to unlink a tophat that does not have a wearer\\n /// @dev This ensures that unlinking never results in a bricked tophat\\n error InvalidUnlink();\\n\\n /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address\\n error ZeroAddress();\\n\\n /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters)\\n /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI\\n /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()`\\n error StringTooLong();\\n}\\n\",\"keccak256\":\"0x81b0056b7bed86eabc07c0e4a9655c586ddb8e6c128320593669b76efd5a08de\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/HatsEvents.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface HatsEvents {\\n /// @notice Emitted when a new hat is created\\n /// @param id The id for the new hat\\n /// @param details A description of the Hat\\n /// @param maxSupply The total instances of the Hat that can be worn at once\\n /// @param eligibility The address that can report on the Hat wearer's status\\n /// @param toggle The address that can deactivate the Hat\\n /// @param mutable_ Whether the hat's properties are changeable after creation\\n /// @param imageURI The image uri for this hat and the fallback for its\\n event HatCreated(\\n uint256 id,\\n string details,\\n uint32 maxSupply,\\n address eligibility,\\n address toggle,\\n bool mutable_,\\n string imageURI\\n );\\n\\n /// @notice Emitted when a hat wearer's standing is updated\\n /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction\\n /// @param hatId The id of the wearer's hat\\n /// @param wearer The wearer's address\\n /// @param wearerStanding Whether the wearer is in good standing for the hat\\n event WearerStandingChanged(\\n uint256 hatId,\\n address wearer,\\n bool wearerStanding\\n );\\n\\n /// @notice Emitted when a hat's status is updated\\n /// @param hatId The id of the hat\\n /// @param newStatus Whether the hat is active\\n event HatStatusChanged(uint256 hatId, bool newStatus);\\n\\n /// @notice Emitted when a hat's details are updated\\n /// @param hatId The id of the hat\\n /// @param newDetails The updated details\\n event HatDetailsChanged(uint256 hatId, string newDetails);\\n\\n /// @notice Emitted when a hat's eligibility module is updated\\n /// @param hatId The id of the hat\\n /// @param newEligibility The updated eligibiliy module\\n event HatEligibilityChanged(uint256 hatId, address newEligibility);\\n\\n /// @notice Emitted when a hat's toggle module is updated\\n /// @param hatId The id of the hat\\n /// @param newToggle The updated toggle module\\n event HatToggleChanged(uint256 hatId, address newToggle);\\n\\n /// @notice Emitted when a hat's mutability is updated\\n /// @param hatId The id of the hat\\n event HatMutabilityChanged(uint256 hatId);\\n\\n /// @notice Emitted when a hat's maximum supply is updated\\n /// @param hatId The id of the hat\\n /// @param newMaxSupply The updated max supply\\n event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply);\\n\\n /// @notice Emitted when a hat's image URI is updated\\n /// @param hatId The id of the hat\\n /// @param newImageURI The updated image URI\\n event HatImageURIChanged(uint256 hatId, string newImageURI);\\n\\n /// @notice Emitted when a tophat linkage is requested by its admin\\n /// @param domain The domain of the tree tophat to link\\n /// @param newAdmin The tophat's would-be admin in the parent tree\\n event TopHatLinkRequested(uint32 domain, uint256 newAdmin);\\n\\n /// @notice Emitted when a tophat is linked to a another tree\\n /// @param domain The domain of the newly-linked tophat\\n /// @param newAdmin The tophat's new admin in the parent tree\\n event TopHatLinked(uint32 domain, uint256 newAdmin);\\n}\\n\",\"keccak256\":\"0x53413397d15e1636c3cd7bd667656b79bc2886785403b824bcd4ed122667f2c6\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\nimport \\\"./IHatsIdUtilities.sol\\\";\\nimport \\\"./HatsErrors.sol\\\";\\nimport \\\"./HatsEvents.sol\\\";\\n\\ninterface IHats is IHatsIdUtilities, HatsErrors, HatsEvents {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function batchCreateHats(\\n uint256[] calldata _admins,\\n string[] calldata _details,\\n uint32[] calldata _maxSupplies,\\n address[] memory _eligibilityModules,\\n address[] memory _toggleModules,\\n bool[] calldata _mutables,\\n string[] calldata _imageURIs\\n ) external returns (bool success);\\n\\n function getNextId(uint256 _admin) external view returns (uint256 nextId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function batchMintHats(\\n uint256[] calldata _hatIds,\\n address[] calldata _wearers\\n ) external returns (bool success);\\n\\n function setHatStatus(\\n uint256 _hatId,\\n bool _newStatus\\n ) external returns (bool toggled);\\n\\n function checkHatStatus(uint256 _hatId) external returns (bool toggled);\\n\\n function setHatWearerStatus(\\n uint256 _hatId,\\n address _wearer,\\n bool _eligible,\\n bool _standing\\n ) external returns (bool updated);\\n\\n function checkHatWearerStatus(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool updated);\\n\\n function renounceHat(uint256 _hatId) external;\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n HATS ADMIN FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function makeHatImmutable(uint256 _hatId) external;\\n\\n function changeHatDetails(\\n uint256 _hatId,\\n string memory _newDetails\\n ) external;\\n\\n function changeHatEligibility(\\n uint256 _hatId,\\n address _newEligibility\\n ) external;\\n\\n function changeHatToggle(uint256 _hatId, address _newToggle) external;\\n\\n function changeHatImageURI(\\n uint256 _hatId,\\n string memory _newImageURI\\n ) external;\\n\\n function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external;\\n\\n function requestLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat\\n ) external;\\n\\n function approveLinkTopHatToTree(\\n uint32 _topHatId,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external;\\n\\n function relinkTopHatWithinTree(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat,\\n address _eligibility,\\n address _toggle,\\n string calldata _details,\\n string calldata _imageURI\\n ) external;\\n\\n /*//////////////////////////////////////////////////////////////\\n VIEW FUNCTIONS\\n //////////////////////////////////////////////////////////////*/\\n\\n function viewHat(\\n uint256 _hatId\\n )\\n external\\n view\\n returns (\\n string memory details,\\n uint32 maxSupply,\\n uint32 supply,\\n address eligibility,\\n address toggle,\\n string memory imageURI,\\n uint16 lastHatId,\\n bool mutable_,\\n bool active\\n );\\n\\n function isWearerOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isWearer);\\n\\n function isAdminOfHat(\\n address _user,\\n uint256 _hatId\\n ) external view returns (bool isAdmin);\\n\\n function isInGoodStanding(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool standing);\\n\\n function isEligible(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible);\\n\\n function getHatEligibilityModule(\\n uint256 _hatId\\n ) external view returns (address eligibility);\\n\\n function getHatToggleModule(\\n uint256 _hatId\\n ) external view returns (address toggle);\\n\\n function getHatMaxSupply(\\n uint256 _hatId\\n ) external view returns (uint32 maxSupply);\\n\\n function hatSupply(uint256 _hatId) external view returns (uint32 supply);\\n\\n function getImageURIForHat(\\n uint256 _hatId\\n ) external view returns (string memory _uri);\\n\\n function balanceOf(\\n address wearer,\\n uint256 hatId\\n ) external view returns (uint256 balance);\\n\\n function balanceOfBatch(\\n address[] calldata _wearers,\\n uint256[] calldata _hatIds\\n ) external view returns (uint256[] memory);\\n\\n function uri(uint256 id) external view returns (string memory _uri);\\n}\\n\",\"keccak256\":\"0x2867004bddc5148fa1937f25c0403e5d9977583aaf50fdbdb74bd463f64f21c8\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHatsIdUtilities.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHatsIdUtilities {\\n function buildHatId(\\n uint256 _admin,\\n uint16 _newHat\\n ) external pure returns (uint256 id);\\n\\n function getHatLevel(uint256 _hatId) external view returns (uint32 level);\\n\\n function getLocalHatLevel(\\n uint256 _hatId\\n ) external pure returns (uint32 level);\\n\\n function isTopHat(uint256 _hatId) external view returns (bool _topHat);\\n\\n function isLocalTopHat(\\n uint256 _hatId\\n ) external pure returns (bool _localTopHat);\\n\\n function isValidHatId(\\n uint256 _hatId\\n ) external view returns (bool validHatId);\\n\\n function getAdminAtLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external view returns (uint256 admin);\\n\\n function getAdminAtLocalLevel(\\n uint256 _hatId,\\n uint32 _level\\n ) external pure returns (uint256 admin);\\n\\n function getTopHatDomain(\\n uint256 _hatId\\n ) external view returns (uint32 domain);\\n\\n function getTippyTopHatDomain(\\n uint32 _topHatDomain\\n ) external view returns (uint32 domain);\\n\\n function noCircularLinkage(\\n uint32 _topHatDomain,\\n uint256 _linkedAdmin\\n ) external view returns (bool notCircular);\\n\\n function sameTippyTopHatDomain(\\n uint32 _topHatDomain,\\n uint256 _newAdminHat\\n ) external view returns (bool sameDomain);\\n}\\n\",\"keccak256\":\"0x007fcc07b20bf84bacad1f9a2ddf4e30e1a8be961e144b7bef8e98a51781aee9\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/hats/IHatsModuleFactory.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.19;\\n\\ninterface IHatsModuleFactory {\\n error HatsModuleFactory_ModuleAlreadyDeployed(\\n address implementation,\\n uint256 hatId,\\n bytes otherImmutableArgs,\\n uint256 saltNonce\\n );\\n\\n error BatchArrayLengthMismatch();\\n\\n event HatsModuleFactory_ModuleDeployed(\\n address implementation,\\n address instance,\\n uint256 hatId,\\n bytes otherImmutableArgs,\\n bytes initData,\\n uint256 saltNonce\\n );\\n\\n function HATS() external view returns (address);\\n\\n function version() external view returns (string memory);\\n\\n function createHatsModule(\\n address _implementation,\\n uint256 _hatId,\\n bytes calldata _otherImmutableArgs,\\n bytes calldata _initData,\\n uint256 _saltNonce\\n ) external returns (address _instance);\\n\\n function batchCreateHatsModule(\\n address[] calldata _implementations,\\n uint256[] calldata _hatIds,\\n bytes[] calldata _otherImmutableArgsArray,\\n bytes[] calldata _initDataArray,\\n uint256[] calldata _saltNonces\\n ) external returns (bool success);\\n\\n function getHatsModuleAddress(\\n address _implementation,\\n uint256 _hatId,\\n bytes calldata _otherImmutableArgs,\\n uint256 _saltNonce\\n ) external view returns (address);\\n\\n function deployed(\\n address _implementation,\\n uint256 _hatId,\\n bytes calldata _otherImmutableArgs,\\n uint256 _saltNonce\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x861faf40785cedb829243116d492653414a367853408a5c27d201522f6c3bfdd\",\"license\":\"MIT\"},\"contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.13;\\n\\ninterface IHatsElectionsEligibility {\\n event ElectionOpened(uint128 nextTermEnd);\\n event ElectionCompleted(uint128 termEnd, address[] winners);\\n event NewTermStarted(uint128 termEnd);\\n event Recalled(uint128 termEnd, address[] accounts);\\n\\n /// @notice Returns the first second after the current term ends.\\n /// @dev Also serves as the id for the current term.\\n function currentTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the first second after the next term ends.\\n /// @dev Also serves as the id for the next term.\\n function nextTermEnd() external view returns (uint128);\\n\\n /// @notice Returns the election status (open or closed) for a given term end.\\n /// @param termEnd The term end timestamp to query.\\n function electionStatus(\\n uint128 termEnd\\n ) external view returns (bool isElectionOpen);\\n\\n /// @notice Returns whether a candidate was elected in a given term.\\n /// @param termEnd The term end timestamp to query.\\n /// @param candidate The address of the candidate.\\n function electionResults(\\n uint128 termEnd,\\n address candidate\\n ) external view returns (bool elected);\\n\\n /// @notice Returns the BALLOT_BOX_HAT constant.\\n function BALLOT_BOX_HAT() external pure returns (uint256);\\n\\n /// @notice Returns the ADMIN_HAT constant.\\n function ADMIN_HAT() external pure returns (uint256);\\n\\n /**\\n * @notice Submit the results of an election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the election results are being submitted.\\n * @param _winners The addresses of the winners of the election.\\n */\\n function elect(uint128 _termEnd, address[] calldata _winners) external;\\n\\n /**\\n * @notice Submit the results of a recall election for a specified term.\\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\\n * @param _termEnd The id of the term for which the recall results are being submitted.\\n * @param _recallees The addresses to be recalled.\\n */\\n function recall(uint128 _termEnd, address[] calldata _recallees) external;\\n\\n /**\\n * @notice Set the next term and open the election for it.\\n * @dev Only callable by the wearer(s) of the ADMIN_HAT.\\n * @param _newTermEnd The id of the term that will be opened.\\n */\\n function setNextTerm(uint128 _newTermEnd) external;\\n\\n /**\\n * @notice Start the next term, updating the current term.\\n * @dev Can be called by anyone, but will revert if conditions are not met.\\n */\\n function startNextTerm() external;\\n\\n /**\\n * @notice Determine the eligibility and standing of a wearer for a hat.\\n * @param _wearer The address of the hat wearer.\\n * @param _hatId The ID of the hat.\\n * @return eligible True if the wearer is eligible for the hat.\\n * @return standing True if the wearer is in good standing.\\n */\\n function getWearerStatus(\\n address _wearer,\\n uint256 _hatId\\n ) external view returns (bool eligible, bool standing);\\n}\\n\",\"keccak256\":\"0x74dfc5d538d866ddb8ee2ca1b569abf62e02d848c59f308adf6075ecff175c7d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nimport {Lockup, LockupLinear} from \\\"./types/DataTypes.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./ISablierV2Lockup.sol\\\";\\n\\n/// @title ISablierV2LockupLinear\\n/// @notice Creates and manages Lockup streams with a linear distribution function.\\ninterface ISablierV2LockupLinear is ISablierV2Lockup {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when a stream is created.\\n /// @param streamId The ID of the newly created stream.\\n /// @param funder The address which funded the stream.\\n /// @param sender The address distributing the assets, which will have the ability to cancel the stream.\\n /// @param recipient The address receiving the assets.\\n /// @param amounts Struct encapsulating (i) the deposit amount, and (ii) the broker fee amount, both denoted\\n /// in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Boolean indicating whether the stream will be cancelable or not.\\n /// @param transferable Boolean indicating whether the stream NFT is transferable or not.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker The address of the broker who has helped create the stream, e.g. a front-end website.\\n event CreateLockupLinearStream(\\n uint256 streamId,\\n address funder,\\n address indexed sender,\\n address indexed recipient,\\n Lockup.CreateAmounts amounts,\\n IERC20 indexed asset,\\n bool cancelable,\\n bool transferable,\\n LockupLinear.Timestamps timestamps,\\n address broker\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the stream's cliff time, which is a Unix timestamp. A value of zero means there\\n /// is no cliff.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getCliffTime(\\n uint256 streamId\\n ) external view returns (uint40 cliffTime);\\n\\n /// @notice Retrieves the full stream details.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n /// @return stream See the documentation in {DataTypes}.\\n function getStream(\\n uint256 streamId\\n ) external view returns (LockupLinear.StreamLL memory stream);\\n\\n /// @notice Retrieves the stream's start, cliff and end timestamps.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n /// @return timestamps See the documentation in {DataTypes}.\\n function getTimestamps(\\n uint256 streamId\\n ) external view returns (LockupLinear.Timestamps memory timestamps);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Creates a stream by setting the start time to `block.timestamp`, and the end time to\\n /// the sum of `block.timestamp` and `params.durations.total`. The stream is funded by `msg.sender` and is wrapped\\n /// in an ERC-721 NFT.\\n ///\\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\\n ///\\n /// Requirements:\\n /// - All requirements in {createWithTimestamps} must be met for the calculated parameters.\\n ///\\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\\n /// @return streamId The ID of the newly created stream.\\n function createWithDurations(\\n LockupLinear.CreateWithDurations calldata params\\n ) external returns (uint256 streamId);\\n\\n /// @notice Creates a stream with the provided start time and end time. The stream is funded by `msg.sender` and is\\n /// wrapped in an ERC-721 NFT.\\n ///\\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\\n ///\\n /// Notes:\\n /// - A cliff time of zero means there is no cliff.\\n /// - As long as the times are ordered, it is not an error for the start or the cliff time to be in the past.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `params.totalAmount` must be greater than zero.\\n /// - If set, `params.broker.fee` must not be greater than `MAX_BROKER_FEE`.\\n /// - `params.timestamps.start` must be greater than zero and less than `params.timestamps.end`.\\n /// - If set, `params.timestamps.cliff` must be greater than `params.timestamps.start` and less than\\n /// `params.timestamps.end`.\\n /// - `params.timestamps.end` must be in the future.\\n /// - `params.recipient` must not be the zero address.\\n /// - `msg.sender` must have allowed this contract to spend at least `params.totalAmount` assets.\\n ///\\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\\n /// @return streamId The ID of the newly created stream.\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0x064264723114b1f1cf3953fd79874dfcbb42cf313857aee6d5e6b09a23e0010b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b50611dd58061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063ba9a91a51461003b578063d58041b714610062575b600080fd5b610050600080516020611d8083398151915281565b60405190815260200160405180910390f35b61007561007036600461122f565b610077565b005b60006100866020830183611289565b9050600061009a60e0840160c08501611289565b905060006100ae6040850160208601611289565b90506000806100e58584866100c960a08b0160808c01611289565b6100d76101008c018c6112b6565b6100e09061141a565b6101d7565b90925090506000610136868587868661010460808e0160608f01611289565b8d60a00160208101906101179190611289565b8e806101200190610128919061148a565b610131906114b9565b6105ad565b905060005b61014961014089018961153c565b90508110156101cd5760006101626101408a018a61153c565b838181106101725761017261158c565b905060200281019061018491906115a2565b61018d9061179b565b90506101c488878988888e60400160208101906101aa9190611289565b8f60e00160208101906101bd9190611289565b8a89610938565b5060010161013b565b5050505050505050565b60408051600481526024810182526020810180516001600160e01b0316633f0f816960e21b17905290516000918291829182916001600160a01b038b169161021e9161189e565b6000604051808303816000865af19150503d806000811461025b576040519150601f19603f3d011682016040523d82523d6000602084013e610260565b606091505b5091509150816102b65760405162461bcd60e51b815260206004820152601a60248201527f4661696c656420746f20676574206c617374546f704861744964000000000000604482015260640160405180910390fd5b60e0818060200190518101906102cc91906118b0565b6102d79060016118df565b901b9350336001600160a01b031663468721a78a60003389600001518a6020015160405160240161030a93929190611924565b60408051601f198184030181529181526020820180516001600160e01b0316631a64dfad60e01b1790525160e085901b6001600160e01b03191681526103589392919060009060040161195a565b6020604051808303816000875af1158015610377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039b91906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f906103de908a90600080516020611d808339815191529046908f908b906004016119cd565b6020604051808303816000875af11580156103fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104219190611a00565b60408051600180825281830190925291945060009190816020015b606081526020019060019003908161043c57505060408051600180825281830190925291925060009190602082015b606081526020019060019003908161046b579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b815250826000815181106104b6576104b661158c565b60200260200101819052506104ca86610996565b816000815181106104dd576104dd61158c565b6020026020010181905250336001600160a01b031663468721a7896000858560405160240161050d929190611a79565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b031916815261055b9392919060009060040161195a565b6020604051808303816000875af115801561057a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059e91906119b0565b50505050509550959350505050565b60405162460ea360e61b8152600481018690526000906001600160a01b038a1690631183a8c090602401602060405180830381865afa1580156105f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061891906118b0565b9050336001600160a01b031663468721a78a600089866000015160018b8c8a604001518b602001516040516024016106569796959493929190611aa7565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b03191681526106a49392919060009060040161195a565b6020604051808303816000875af11580156106c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e791906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f9061072a908a90600080516020611d808339815191529046908f9088906004016119cd565b6020604051808303816000875af1158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190611a00565b506000846001600160a01b031663f1ab873c85604051806020016040528060008152506040516024016107a09190611b08565b60408051601f19818403018152918152602080830180516001600160e01b031663a4f9edbf60e01b17905290516107f291600080516020611d8083398151915291899101918252602082015260400190565b60408051601f198184030181529082905280516020909101206001600160e01b031960e086901b16825261082a939291600401611b1b565b6020604051808303816000875af1158015610849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086d9190611a00565b604051602481018490526001600160a01b0382166044820152909150339063468721a7908c9060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b03191681526108e79392919060009060040161195a565b6020604051808303816000875af1158015610906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092a91906119b0565b505098975050505050505050565b600061094d8a86868a8a888860800151610a9e565b9050600061095e8b8585858b610c05565b905060006109788b8b8e8760800151886000015187610f37565b9050610988846060015182610fe1565b505050505050505050505050565b6060816000036109bd5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156109e757806109d181611b4f565b91506109e09050600a83611b7e565b91506109c1565b6000816001600160401b03811115610a0157610a016112d6565b6040519080825280601f01601f191660200182016040528015610a2b576020820181803683370190505b5090505b8415610a9657610a40600183611b92565b9150610a4d600a86611ba5565b610a589060306118df565b60f81b818381518110610a6d57610a6d61158c565b60200101906001600160f81b031916908160001a905350610a8f600a86611b7e565b9450610a2f565b949350505050565b60006001600160801b03821615610bf757866001600160a01b0316632f7fb7b6878a6001600160a01b0316631183a8c0876040518263ffffffff1660e01b8152600401610aed91815260200190565b602060405180830381865afa158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e91906118b0565b886000604051602001610b4b929190918252602082015260400190565b60408051601f198184030181528282526001600160801b0389166020840152910160408051601f19818403018152908290526001600160e01b031960e087901b168252610bad94939291600080516020611d8083398151915290600401611bb9565b6020604051808303816000875af1158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611a00565b9050610bfa565b50825b979650505050505050565b60405162460ea360e61b81526004810185905260009081906001600160a01b03881690631183a8c090602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7291906118b0565b9050336001600160a01b031663468721a78860008989602001518a60a001518a8a8d60c001518e60400151604051602401610cb39796959493929190611c05565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b0319168152610d019392919060009060040161195a565b6020604051808303816000875af1158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4491906119b0565b5060808501516001600160801b031615610e6f5760408051600180825281830190925260009160208083019080368337019050509050856000015181600081518110610d9257610d9261158c565b60200260200101906001600160a01b031690816001600160a01b031681525050336001600160a01b031663468721a7866000896080015185604051602401610ddb929190611c5b565b60408051601f198184030181529181526020820180516001600160e01b0316634a231cef60e01b1790525160e085901b6001600160e01b0319168152610e299392919060009060040161195a565b6020604051808303816000875af1158015610e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6c91906119b0565b50505b8451604051602481018390526001600160a01b039091166044820152339063468721a790899060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b0319168152610ee99392919060009060040161195a565b6020604051808303816000875af1158015610f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2c91906119b0565b509695505050505050565b60006001600160801b03841615610f4f575081610fd7565b604051638a54c52f60e01b81526001600160a01b03881690638a54c52f90610f91908990600080516020611d808339815191529046908b9089906004016119cd565b6020604051808303816000875af1158015610fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd49190611a00565b90505b9695505050505050565b60005b825181101561122a5760008382815181106110015761100161158c565b60200260200101519050336001600160a01b031663468721a78260400151600084600001518560a001516040516024016110599291906001600160a01b039290921682526001600160801b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526110a79392919060009060040161195a565b6020604051808303816000875af11580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea91906119b0565b50336001600160a01b031663468721a78260000151600060405180610100016040528086602001516001600160a01b03168152602001886001600160a01b031681526020018660a001516001600160801b0316815260200186604001516001600160a01b031681526020018660c00151151581526020018660e001511515815260200186606001518152602001866080015181525060405160240161118f9190611cb0565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526111dd9392919060009060040161195a565b6020604051808303816000875af11580156111fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122091906119b0565b5050600101610fe4565b505050565b60006020828403121561124157600080fd5b81356001600160401b0381111561125757600080fd5b8201610160818503121561126a57600080fd5b9392505050565b6001600160a01b038116811461128657600080fd5b50565b60006020828403121561129b57600080fd5b813561126a81611271565b80356112b181611271565b919050565b60008235603e198336030181126112cc57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561130e5761130e6112d6565b60405290565b604051606081016001600160401b038111828210171561130e5761130e6112d6565b60405161010081016001600160401b038111828210171561130e5761130e6112d6565b60405160e081016001600160401b038111828210171561130e5761130e6112d6565b604051601f8201601f191681016001600160401b03811182821017156113a3576113a36112d6565b604052919050565b600082601f8301126113bc57600080fd5b81356001600160401b038111156113d5576113d56112d6565b6113e8601f8201601f191660200161137b565b8181528460208386010111156113fd57600080fd5b816020850160208301376000918101602001919091529392505050565b60006040823603121561142c57600080fd5b6114346112ec565b82356001600160401b0381111561144a57600080fd5b611456368286016113ab565b82525060208301356001600160401b0381111561147257600080fd5b61147e368286016113ab565b60208301525092915050565b60008235605e198336030181126112cc57600080fd5b801515811461128657600080fd5b80356112b1816114a0565b6000606082360312156114cb57600080fd5b6114d3611314565b82356001600160401b038111156114e957600080fd5b6114f5368286016113ab565b82525060208301356001600160401b0381111561151157600080fd5b61151d368286016113ab565b6020830152506040830135611531816114a0565b604082015292915050565b6000808335601e1984360301811261155357600080fd5b8301803591506001600160401b0382111561156d57600080fd5b6020019150600581901b360382131561158557600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b6000823560de198336030181126112cc57600080fd5b803564ffffffffff811681146112b157600080fd5b6000606082840312156115df57600080fd5b6115e7611314565b90506115f2826115b8565b8152611600602083016115b8565b6020820152611531604083016115b8565b60006040828403121561162357600080fd5b61162b6112ec565b9050813561163881611271565b808252506020820135602082015292915050565b80356001600160801b03811681146112b157600080fd5b600082601f83011261167457600080fd5b81356001600160401b0381111561168d5761168d6112d6565b61169c60208260051b0161137b565b80828252602082019150602061016084028601019250858311156116bf57600080fd5b602085015b8381101561177d5761016081880312156116dd57600080fd5b6116e5611336565b6116ee826112a6565b81526116fc602083016112a6565b602082015261170d604083016112a6565b604082015261171f88606084016115cd565b60608201526117318860c08401611611565b6080820152611743610100830161164c565b60a082015261175561012083016114ae565b60c082015261176761014083016114ae565b60e08201528352602090920191610160016116c4565b5095945050505050565b803563ffffffff811681146112b157600080fd5b600060e082360312156117ad57600080fd5b6117b5611359565b6117be836112a6565b815260208301356001600160401b038111156117d957600080fd5b6117e5368286016113ab565b60208301525060408301356001600160401b0381111561180457600080fd5b611810368286016113ab565b60408301525060608301356001600160401b0381111561182f57600080fd5b61183b36828601611663565b60608301525061184d6080840161164c565b608082015261185e60a08401611787565b60a082015261186f60c084016114ae565b60c082015292915050565b60005b8381101561189557818101518382015260200161187d565b50506000910152565b600082516112cc81846020870161187a565b6000602082840312156118c257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156118f2576118f26118c9565b92915050565b6000815180845261191081602086016020860161187a565b601f01601f19169290920160200192915050565b6001600160a01b0384168152606060208201819052600090611948908301856118f8565b8281036040840152610fd781856118f8565b60018060a01b038516815283602082015260806040820152600061198160808301856118f8565b9050600283106119a157634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b6000602082840312156119c257600080fd5b815161126a816114a0565b6001600160a01b039586168152602081019490945260408401929092529092166060820152608081019190915260a00190565b600060208284031215611a1257600080fd5b815161126a81611271565b600082825180855260208501945060208160051b8301016020850160005b83811015611a6d57601f19858403018852611a578383516118f8565b6020988901989093509190910190600101611a3b565b50909695505050505050565b604081526000611a8c6040830185611a1d565b8281036020840152611a9e8185611a1d565b95945050505050565b87815260e060208201526000611ac060e08301896118f8565b60ff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b9a9950505050505050505050565b60208152600061126a60208301846118f8565b6001600160a01b0384168152606060208201819052600090611b3f908301856118f8565b9050826040830152949350505050565b600060018201611b6157611b616118c9565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611b8d57611b8d611b68565b500490565b818103818111156118f2576118f26118c9565b600082611bb457611bb4611b68565b500690565b60018060a01b038616815284602082015260a060408201526000611be060a08301866118f8565b8281036060840152611bf281866118f8565b9150508260808301529695505050505050565b87815260e060208201526000611c1e60e08301896118f8565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b6000604082016001600160801b03851683526040602084015280845180835260608501915060208601925060005b81811015611a6d5783516001600160a01b0316835260209384019390920191600101611c89565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b03169083015260608084015191821690830152610160820190506080830151611d05608084018215159052565b5060a0830151611d1960a084018215159052565b5060c0830151611d5860c084018264ffffffffff815116825264ffffffffff602082015116602083015264ffffffffff60408201511660408301525050565b5060e0929092015180516001600160a01b031661012083015260200151610140909101529056fe5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072a264697066735822122003333a52c72d7fd00bfc049716b8e9b315c6d7df7e1feb6b71816b75fc06b82264736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063ba9a91a51461003b578063d58041b714610062575b600080fd5b610050600080516020611d8083398151915281565b60405190815260200160405180910390f35b61007561007036600461122f565b610077565b005b60006100866020830183611289565b9050600061009a60e0840160c08501611289565b905060006100ae6040850160208601611289565b90506000806100e58584866100c960a08b0160808c01611289565b6100d76101008c018c6112b6565b6100e09061141a565b6101d7565b90925090506000610136868587868661010460808e0160608f01611289565b8d60a00160208101906101179190611289565b8e806101200190610128919061148a565b610131906114b9565b6105ad565b905060005b61014961014089018961153c565b90508110156101cd5760006101626101408a018a61153c565b838181106101725761017261158c565b905060200281019061018491906115a2565b61018d9061179b565b90506101c488878988888e60400160208101906101aa9190611289565b8f60e00160208101906101bd9190611289565b8a89610938565b5060010161013b565b5050505050505050565b60408051600481526024810182526020810180516001600160e01b0316633f0f816960e21b17905290516000918291829182916001600160a01b038b169161021e9161189e565b6000604051808303816000865af19150503d806000811461025b576040519150601f19603f3d011682016040523d82523d6000602084013e610260565b606091505b5091509150816102b65760405162461bcd60e51b815260206004820152601a60248201527f4661696c656420746f20676574206c617374546f704861744964000000000000604482015260640160405180910390fd5b60e0818060200190518101906102cc91906118b0565b6102d79060016118df565b901b9350336001600160a01b031663468721a78a60003389600001518a6020015160405160240161030a93929190611924565b60408051601f198184030181529181526020820180516001600160e01b0316631a64dfad60e01b1790525160e085901b6001600160e01b03191681526103589392919060009060040161195a565b6020604051808303816000875af1158015610377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039b91906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f906103de908a90600080516020611d808339815191529046908f908b906004016119cd565b6020604051808303816000875af11580156103fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104219190611a00565b60408051600180825281830190925291945060009190816020015b606081526020019060019003908161043c57505060408051600180825281830190925291925060009190602082015b606081526020019060019003908161046b579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b815250826000815181106104b6576104b661158c565b60200260200101819052506104ca86610996565b816000815181106104dd576104dd61158c565b6020026020010181905250336001600160a01b031663468721a7896000858560405160240161050d929190611a79565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b031916815261055b9392919060009060040161195a565b6020604051808303816000875af115801561057a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059e91906119b0565b50505050509550959350505050565b60405162460ea360e61b8152600481018690526000906001600160a01b038a1690631183a8c090602401602060405180830381865afa1580156105f4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061891906118b0565b9050336001600160a01b031663468721a78a600089866000015160018b8c8a604001518b602001516040516024016106569796959493929190611aa7565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b03191681526106a49392919060009060040161195a565b6020604051808303816000875af11580156106c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e791906119b0565b50604051638a54c52f60e01b81526001600160a01b03891690638a54c52f9061072a908a90600080516020611d808339815191529046908f9088906004016119cd565b6020604051808303816000875af1158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d9190611a00565b506000846001600160a01b031663f1ab873c85604051806020016040528060008152506040516024016107a09190611b08565b60408051601f19818403018152918152602080830180516001600160e01b031663a4f9edbf60e01b17905290516107f291600080516020611d8083398151915291899101918252602082015260400190565b60408051601f198184030181529082905280516020909101206001600160e01b031960e086901b16825261082a939291600401611b1b565b6020604051808303816000875af1158015610849573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086d9190611a00565b604051602481018490526001600160a01b0382166044820152909150339063468721a7908c9060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b03191681526108e79392919060009060040161195a565b6020604051808303816000875af1158015610906573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092a91906119b0565b505098975050505050505050565b600061094d8a86868a8a888860800151610a9e565b9050600061095e8b8585858b610c05565b905060006109788b8b8e8760800151886000015187610f37565b9050610988846060015182610fe1565b505050505050505050505050565b6060816000036109bd5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156109e757806109d181611b4f565b91506109e09050600a83611b7e565b91506109c1565b6000816001600160401b03811115610a0157610a016112d6565b6040519080825280601f01601f191660200182016040528015610a2b576020820181803683370190505b5090505b8415610a9657610a40600183611b92565b9150610a4d600a86611ba5565b610a589060306118df565b60f81b818381518110610a6d57610a6d61158c565b60200101906001600160f81b031916908160001a905350610a8f600a86611b7e565b9450610a2f565b949350505050565b60006001600160801b03821615610bf757866001600160a01b0316632f7fb7b6878a6001600160a01b0316631183a8c0876040518263ffffffff1660e01b8152600401610aed91815260200190565b602060405180830381865afa158015610b0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2e91906118b0565b886000604051602001610b4b929190918252602082015260400190565b60408051601f198184030181528282526001600160801b0389166020840152910160408051601f19818403018152908290526001600160e01b031960e087901b168252610bad94939291600080516020611d8083398151915290600401611bb9565b6020604051808303816000875af1158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611a00565b9050610bfa565b50825b979650505050505050565b60405162460ea360e61b81526004810185905260009081906001600160a01b03881690631183a8c090602401602060405180830381865afa158015610c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7291906118b0565b9050336001600160a01b031663468721a78860008989602001518a60a001518a8a8d60c001518e60400151604051602401610cb39796959493929190611c05565b60408051601f198184030181529181526020820180516001600160e01b0316635829492f60e11b1790525160e085901b6001600160e01b0319168152610d019392919060009060040161195a565b6020604051808303816000875af1158015610d20573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4491906119b0565b5060808501516001600160801b031615610e6f5760408051600180825281830190925260009160208083019080368337019050509050856000015181600081518110610d9257610d9261158c565b60200260200101906001600160a01b031690816001600160a01b031681525050336001600160a01b031663468721a7866000896080015185604051602401610ddb929190611c5b565b60408051601f198184030181529181526020820180516001600160e01b0316634a231cef60e01b1790525160e085901b6001600160e01b0319168152610e299392919060009060040161195a565b6020604051808303816000875af1158015610e48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6c91906119b0565b50505b8451604051602481018390526001600160a01b039091166044820152339063468721a790899060009060640160408051601f198184030181529181526020820180516001600160e01b031663320fbbb760e11b1790525160e085901b6001600160e01b0319168152610ee99392919060009060040161195a565b6020604051808303816000875af1158015610f08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f2c91906119b0565b509695505050505050565b60006001600160801b03841615610f4f575081610fd7565b604051638a54c52f60e01b81526001600160a01b03881690638a54c52f90610f91908990600080516020611d808339815191529046908b9089906004016119cd565b6020604051808303816000875af1158015610fb0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd49190611a00565b90505b9695505050505050565b60005b825181101561122a5760008382815181106110015761100161158c565b60200260200101519050336001600160a01b031663468721a78260400151600084600001518560a001516040516024016110599291906001600160a01b039290921682526001600160801b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526110a79392919060009060040161195a565b6020604051808303816000875af11580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea91906119b0565b50336001600160a01b031663468721a78260000151600060405180610100016040528086602001516001600160a01b03168152602001886001600160a01b031681526020018660a001516001600160801b0316815260200186604001516001600160a01b031681526020018660c00151151581526020018660e001511515815260200186606001518152602001866080015181525060405160240161118f9190611cb0565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526111dd9392919060009060040161195a565b6020604051808303816000875af11580156111fc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122091906119b0565b5050600101610fe4565b505050565b60006020828403121561124157600080fd5b81356001600160401b0381111561125757600080fd5b8201610160818503121561126a57600080fd5b9392505050565b6001600160a01b038116811461128657600080fd5b50565b60006020828403121561129b57600080fd5b813561126a81611271565b80356112b181611271565b919050565b60008235603e198336030181126112cc57600080fd5b9190910192915050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561130e5761130e6112d6565b60405290565b604051606081016001600160401b038111828210171561130e5761130e6112d6565b60405161010081016001600160401b038111828210171561130e5761130e6112d6565b60405160e081016001600160401b038111828210171561130e5761130e6112d6565b604051601f8201601f191681016001600160401b03811182821017156113a3576113a36112d6565b604052919050565b600082601f8301126113bc57600080fd5b81356001600160401b038111156113d5576113d56112d6565b6113e8601f8201601f191660200161137b565b8181528460208386010111156113fd57600080fd5b816020850160208301376000918101602001919091529392505050565b60006040823603121561142c57600080fd5b6114346112ec565b82356001600160401b0381111561144a57600080fd5b611456368286016113ab565b82525060208301356001600160401b0381111561147257600080fd5b61147e368286016113ab565b60208301525092915050565b60008235605e198336030181126112cc57600080fd5b801515811461128657600080fd5b80356112b1816114a0565b6000606082360312156114cb57600080fd5b6114d3611314565b82356001600160401b038111156114e957600080fd5b6114f5368286016113ab565b82525060208301356001600160401b0381111561151157600080fd5b61151d368286016113ab565b6020830152506040830135611531816114a0565b604082015292915050565b6000808335601e1984360301811261155357600080fd5b8301803591506001600160401b0382111561156d57600080fd5b6020019150600581901b360382131561158557600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b6000823560de198336030181126112cc57600080fd5b803564ffffffffff811681146112b157600080fd5b6000606082840312156115df57600080fd5b6115e7611314565b90506115f2826115b8565b8152611600602083016115b8565b6020820152611531604083016115b8565b60006040828403121561162357600080fd5b61162b6112ec565b9050813561163881611271565b808252506020820135602082015292915050565b80356001600160801b03811681146112b157600080fd5b600082601f83011261167457600080fd5b81356001600160401b0381111561168d5761168d6112d6565b61169c60208260051b0161137b565b80828252602082019150602061016084028601019250858311156116bf57600080fd5b602085015b8381101561177d5761016081880312156116dd57600080fd5b6116e5611336565b6116ee826112a6565b81526116fc602083016112a6565b602082015261170d604083016112a6565b604082015261171f88606084016115cd565b60608201526117318860c08401611611565b6080820152611743610100830161164c565b60a082015261175561012083016114ae565b60c082015261176761014083016114ae565b60e08201528352602090920191610160016116c4565b5095945050505050565b803563ffffffff811681146112b157600080fd5b600060e082360312156117ad57600080fd5b6117b5611359565b6117be836112a6565b815260208301356001600160401b038111156117d957600080fd5b6117e5368286016113ab565b60208301525060408301356001600160401b0381111561180457600080fd5b611810368286016113ab565b60408301525060608301356001600160401b0381111561182f57600080fd5b61183b36828601611663565b60608301525061184d6080840161164c565b608082015261185e60a08401611787565b60a082015261186f60c084016114ae565b60c082015292915050565b60005b8381101561189557818101518382015260200161187d565b50506000910152565b600082516112cc81846020870161187a565b6000602082840312156118c257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156118f2576118f26118c9565b92915050565b6000815180845261191081602086016020860161187a565b601f01601f19169290920160200192915050565b6001600160a01b0384168152606060208201819052600090611948908301856118f8565b8281036040840152610fd781856118f8565b60018060a01b038516815283602082015260806040820152600061198160808301856118f8565b9050600283106119a157634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b6000602082840312156119c257600080fd5b815161126a816114a0565b6001600160a01b039586168152602081019490945260408401929092529092166060820152608081019190915260a00190565b600060208284031215611a1257600080fd5b815161126a81611271565b600082825180855260208501945060208160051b8301016020850160005b83811015611a6d57601f19858403018852611a578383516118f8565b6020988901989093509190910190600101611a3b565b50909695505050505050565b604081526000611a8c6040830185611a1d565b8281036020840152611a9e8185611a1d565b95945050505050565b87815260e060208201526000611ac060e08301896118f8565b60ff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b9a9950505050505050505050565b60208152600061126a60208301846118f8565b6001600160a01b0384168152606060208201819052600090611b3f908301856118f8565b9050826040830152949350505050565b600060018201611b6157611b616118c9565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082611b8d57611b8d611b68565b500490565b818103818111156118f2576118f26118c9565b600082611bb457611bb4611b68565b500690565b60018060a01b038616815284602082015260a060408201526000611be060a08301866118f8565b8281036060840152611bf281866118f8565b9150508260808301529695505050505050565b87815260e060208201526000611c1e60e08301896118f8565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c0840152611afa81856118f8565b6000604082016001600160801b03851683526040602084015280845180835260608501915060208601925060005b81811015611a6d5783516001600160a01b0316835260209384019390920191600101611c89565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b03169083015260608084015191821690830152610160820190506080830151611d05608084018215159052565b5060a0830151611d1960a084018215159052565b5060c0830151611d5860c084018264ffffffffff815116825264ffffffffff602082015116602083015264ffffffffff60408201511660408301525050565b5060e0929092015180516001600160a01b031661012083015260200151610140909101529056fe5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072a264697066735822122003333a52c72d7fd00bfc049716b8e9b315c6d7df7e1feb6b71816b75fc06b82264736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": { - "createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))": { - "details": "For each hat that is included, if the hat is: - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-` on the Sablier contract. - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "createAndDeclareTree((address,address,address,address,address,address,address,address,(string,string),(string,string,bool),(address,string,string,(address,address,address,(uint40,uint40,uint40),(address,uint256),uint128,bool,bool)[],uint128,uint32,bool)[]))": { - "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat to the calling safe.This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/sepolia/DecentSablierStreamManagement.json b/deployments/sepolia/DecentSablierStreamManagement.json deleted file mode 100644 index 7bd98975..00000000 --- a/deployments/sepolia/DecentSablierStreamManagement.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "address": "0x2Eef732Cc457f5B077BEf9588EDc18be6edFC894", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - } - ], - "name": "cancelStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "recipientHatAccount", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "withdrawMaxFromStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x331ae3c9104684a772d336704d341936efc0d71769b59fb0ec76a26e495e0dde", - "receipt": { - "to": null, - "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x2Eef732Cc457f5B077BEf9588EDc18be6edFC894", - "transactionIndex": 38, - "gasUsed": "384429", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5c63ea0482ec8b79d399a038d98200e8925c41255c5631f76e48a79aeebbbdcf", - "transactionHash": "0x331ae3c9104684a772d336704d341936efc0d71769b59fb0ec76a26e495e0dde", - "logs": [], - "blockNumber": 6984775, - "cumulativeGasUsed": "4250856", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 2, - "solcInputHash": "7c4217108daa894b08d16e65df533416", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xbda4bb7894ad5fddd6bd6e98660e4fa78cef606bcf97ea0fee7f3903e74b2bfa\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea264697066735822122062f1800b2f8ec6394c722019479a413b6e548f845021582aa4d800ab37f1c23f64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea264697066735822122062f1800b2f8ec6394c722019479a413b6e548f845021582aa4d800ab37f1c23f64736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json b/deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json deleted file mode 100644 index bcfbe691..00000000 --- a/deployments/sepolia/solcInputs/7c4217108daa894b08d16e65df533416.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "language": "Solidity", - "sources": { - "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafe.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeL2 is GnosisSafe {\n event SafeMultiSigTransaction(\n address to,\n uint256 value,\n bytes data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes signatures,\n // We combine nonce, sender and threshold into one to avoid stack too deep\n // Dev note: additionalInfo should not contain `bytes`, as this complicates decoding\n bytes additionalInfo\n );\n\n event SafeModuleTransaction(address module, address to, uint256 value, bytes data, Enum.Operation operation);\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable override returns (bool) {\n bytes memory additionalInfo;\n {\n additionalInfo = abi.encode(nonce, msg.sender, threshold);\n }\n emit SafeMultiSigTransaction(\n to,\n value,\n data,\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n signatures,\n additionalInfo\n );\n return super.execTransaction(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, signatures);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public override returns (bool success) {\n emit SafeModuleTransaction(msg.sender, to, value, data, operation);\n success = super.execTransactionFromModule(to, value, data, operation);\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Multi Send Call Only - Allows to batch multiple transactions into one, but only calls\n/// @author Stefan George - \n/// @author Richard Meissner - \n/// @notice The guard logic is not required here as this contract doesn't support nested delegate calls\ncontract MultiSendCallOnly {\n /// @dev Sends multiple transactions and reverts all if one fails.\n /// @param transactions Encoded transactions. Each transaction is encoded as a packed bytes of\n /// operation has to be uint8(0) in this version (=> 1 byte),\n /// to as a address (=> 20 bytes),\n /// value as a uint256 (=> 32 bytes),\n /// data length as a uint256 (=> 32 bytes),\n /// data as bytes.\n /// see abi.encodePacked for more information on packed encoding\n /// @notice The code is for most part the same as the normal MultiSend (to keep compatibility),\n /// but reverts if a transaction tries to use a delegatecall.\n /// @notice This method is payable as delegatecalls keep the msg.value from the previous call\n /// If the calling method (e.g. execTransaction) received ETH this would revert otherwise\n function multiSend(bytes memory transactions) public payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let length := mload(transactions)\n let i := 0x20\n for {\n // Pre block is not used in \"while mode\"\n } lt(i, length) {\n // Post block is not used in \"while mode\"\n } {\n // First byte of the data is the operation.\n // We shift by 248 bits (256 - 8 [operation byte]) it right since mload will always load 32 bytes (a word).\n // This will also zero out unused data.\n let operation := shr(0xf8, mload(add(transactions, i)))\n // We offset the load address by 1 byte (operation byte)\n // We shift it right by 96 bits (256 - 160 [20 address bytes]) to right-align the data and zero out unused data.\n let to := shr(0x60, mload(add(transactions, add(i, 0x01))))\n // We offset the load address by 21 byte (operation byte + 20 address bytes)\n let value := mload(add(transactions, add(i, 0x15)))\n // We offset the load address by 53 byte (operation byte + 20 address bytes + 32 value bytes)\n let dataLength := mload(add(transactions, add(i, 0x35)))\n // We offset the load address by 85 byte (operation byte + 20 address bytes + 32 value bytes + 32 data length bytes)\n let data := add(transactions, add(i, 0x55))\n let success := 0\n switch operation\n case 0 {\n success := call(gas(), to, value, data, dataLength, 0, 0)\n }\n // This version does not allow delegatecalls\n case 1 {\n revert(0, 0)\n }\n if eq(success, 0) {\n revert(0, 0)\n }\n // Next entry starts at 85 byte + data length\n i := add(i, add(0x55, dataLength))\n }\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n" - }, - "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n" - }, - "@gnosis.pm/zodiac/contracts/core/Module.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/IAvatar.sol\";\nimport \"../factory/FactoryFriendly.sol\";\nimport \"../guard/Guardable.sol\";\n\nabstract contract Module is FactoryFriendly, Guardable {\n /// @dev Address that will ultimately execute function calls.\n address public avatar;\n /// @dev Address that this module will pass transactions to.\n address public target;\n\n /// @dev Emitted each time the avatar is set.\n event AvatarSet(address indexed previousAvatar, address indexed newAvatar);\n /// @dev Emitted each time the Target is set.\n event TargetSet(address indexed previousTarget, address indexed newTarget);\n\n /// @dev Sets the avatar to a new avatar (`newAvatar`).\n /// @notice Can only be called by the current owner.\n function setAvatar(address _avatar) public onlyOwner {\n address previousAvatar = avatar;\n avatar = _avatar;\n emit AvatarSet(previousAvatar, _avatar);\n }\n\n /// @dev Sets the target to a new target (`newTarget`).\n /// @notice Can only be called by the current owner.\n function setTarget(address _target) public onlyOwner {\n address previousTarget = target;\n target = _target;\n emit TargetSet(previousTarget, _target);\n }\n\n /// @dev Passes a transaction to be executed by the avatar.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function exec(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n success = IAvatar(target).execTransactionFromModule(\n to,\n value,\n data,\n operation\n );\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return success;\n }\n\n /// @dev Passes a transaction to be executed by the target and returns data.\n /// @notice Can only be called by this contract.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execAndReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) internal returns (bool success, bytes memory returnData) {\n /// Check if a transactioon guard is enabled.\n if (guard != address(0)) {\n IGuard(guard).checkTransaction(\n /// Transaction info used by module transactions.\n to,\n value,\n data,\n operation,\n /// Zero out the redundant transaction information only used for Safe multisig transctions.\n 0,\n 0,\n 0,\n address(0),\n payable(0),\n bytes(\"0x\"),\n msg.sender\n );\n }\n (success, returnData) = IAvatar(target)\n .execTransactionFromModuleReturnData(to, value, data, operation);\n if (guard != address(0)) {\n IGuard(guard).checkAfterExecution(bytes32(\"0x\"), success);\n }\n return (success, returnData);\n }\n}\n" - }, - "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\n\nabstract contract FactoryFriendly is OwnableUpgradeable {\n function setUp(bytes memory initializeParams) public virtual;\n}\n" - }, - "@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.8.0;\n\ncontract ModuleProxyFactory {\n event ModuleProxyCreation(\n address indexed proxy,\n address indexed masterCopy\n );\n\n /// `target` can not be zero.\n error ZeroAddress(address target);\n\n /// `address_` is already taken.\n error TakenAddress(address address_);\n\n /// @notice Initialization failed.\n error FailedInitialization();\n\n function createProxy(address target, bytes32 salt)\n internal\n returns (address result)\n {\n if (address(target) == address(0)) revert ZeroAddress(target);\n bytes memory deployment = abi.encodePacked(\n hex\"602d8060093d393df3363d3d373d3d3d363d73\",\n target,\n hex\"5af43d82803e903d91602b57fd5bf3\"\n );\n // solhint-disable-next-line no-inline-assembly\n assembly {\n result := create2(0, add(deployment, 0x20), mload(deployment), salt)\n }\n if (result == address(0)) revert TakenAddress(result);\n }\n\n function deployModule(\n address masterCopy,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (address proxy) {\n proxy = createProxy(\n masterCopy,\n keccak256(abi.encodePacked(keccak256(initializer), saltNonce))\n );\n (bool success, ) = proxy.call(initializer);\n if (!success) revert FailedInitialization();\n\n emit ModuleProxyCreation(proxy, masterCopy);\n }\n}\n" - }, - "@gnosis.pm/zodiac/contracts/guard/BaseGuard.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"../interfaces/IGuard.sol\";\n\nabstract contract BaseGuard is IERC165 {\n function supportsInterface(bytes4 interfaceId)\n external\n pure\n override\n returns (bool)\n {\n return\n interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a\n interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7\n }\n\n /// @dev Module transactions only use the first four parameters: to, value, data, and operation.\n /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.\n /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external virtual;\n\n function checkAfterExecution(bytes32 txHash, bool success) external virtual;\n}\n" - }, - "@gnosis.pm/zodiac/contracts/guard/Guardable.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"./BaseGuard.sol\";\n\n/// @title Guardable - A contract that manages fallback calls made to this contract\ncontract Guardable is OwnableUpgradeable {\n address public guard;\n\n event ChangedGuard(address guard);\n\n /// `guard_` does not implement IERC165.\n error NotIERC165Compliant(address guard_);\n\n /// @dev Set a guard that checks transactions before execution.\n /// @param _guard The address of the guard to be used or the 0 address to disable the guard.\n function setGuard(address _guard) external onlyOwner {\n if (_guard != address(0)) {\n if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))\n revert NotIERC165Compliant(_guard);\n }\n guard = _guard;\n emit ChangedGuard(guard);\n }\n\n function getGuard() external view returns (address _guard) {\n return guard;\n }\n}\n" - }, - "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" - }, - "@gnosis.pm/zodiac/contracts/interfaces/IGuard.sol": { - "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IGuard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotesUpgradeable {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\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. Equivalent to `reinitializer(1)`.\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 * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\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 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 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" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\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 * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\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 value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/extensions/ERC20Snapshot.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/ArraysUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and\n * total supply at the time are recorded for later access.\n *\n * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting.\n * In naive implementations it's possible to perform a \"double spend\" attack by reusing the same balance from different\n * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be\n * used to create an efficient ERC20 forking mechanism.\n *\n * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a\n * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot\n * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id\n * and the account address.\n *\n * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it\n * return `block.number` will trigger the creation of snapshot at the beginning of each new block. When overriding this\n * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract.\n *\n * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient\n * alternative consider {ERC20Votes}.\n *\n * ==== Gas Costs\n *\n * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log\n * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much\n * smaller since identical balances in subsequent snapshots are stored as a single entry.\n *\n * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is\n * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent\n * transfers will have normal cost until the next snapshot, and so on.\n */\n\nabstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable {\n function __ERC20Snapshot_init() internal onlyInitializing {\n }\n\n function __ERC20Snapshot_init_unchained() internal onlyInitializing {\n }\n // Inspired by Jordi Baylina's MiniMeToken to record historical balances:\n // https://github.com/Giveth/minime/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol\n\n using ArraysUpgradeable for uint256[];\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a\n // Snapshot struct, but that would impede usage of functions that work on an array.\n struct Snapshots {\n uint256[] ids;\n uint256[] values;\n }\n\n mapping(address => Snapshots) private _accountBalanceSnapshots;\n Snapshots private _totalSupplySnapshots;\n\n // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid.\n CountersUpgradeable.Counter private _currentSnapshotId;\n\n /**\n * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created.\n */\n event Snapshot(uint256 id);\n\n /**\n * @dev Creates a new snapshot and returns its snapshot id.\n *\n * Emits a {Snapshot} event that contains the same id.\n *\n * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a\n * set of accounts, for example using {AccessControl}, or it may be open to the public.\n *\n * [WARNING]\n * ====\n * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking,\n * you must consider that it can potentially be used by attackers in two ways.\n *\n * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow\n * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target\n * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs\n * section above.\n *\n * We haven't measured the actual numbers; if this is something you're interested in please reach out to us.\n * ====\n */\n function _snapshot() internal virtual returns (uint256) {\n _currentSnapshotId.increment();\n\n uint256 currentId = _getCurrentSnapshotId();\n emit Snapshot(currentId);\n return currentId;\n }\n\n /**\n * @dev Get the current snapshotId\n */\n function _getCurrentSnapshotId() internal view virtual returns (uint256) {\n return _currentSnapshotId.current();\n }\n\n /**\n * @dev Retrieves the balance of `account` at the time `snapshotId` was created.\n */\n function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]);\n\n return snapshotted ? value : balanceOf(account);\n }\n\n /**\n * @dev Retrieves the total supply at the time `snapshotId` was created.\n */\n function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) {\n (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots);\n\n return snapshotted ? value : totalSupply();\n }\n\n // Update balance and/or total supply snapshots before the values are modified. This is implemented\n // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations.\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._beforeTokenTransfer(from, to, amount);\n\n if (from == address(0)) {\n // mint\n _updateAccountSnapshot(to);\n _updateTotalSupplySnapshot();\n } else if (to == address(0)) {\n // burn\n _updateAccountSnapshot(from);\n _updateTotalSupplySnapshot();\n } else {\n // transfer\n _updateAccountSnapshot(from);\n _updateAccountSnapshot(to);\n }\n }\n\n function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) {\n require(snapshotId > 0, \"ERC20Snapshot: id is 0\");\n require(snapshotId <= _getCurrentSnapshotId(), \"ERC20Snapshot: nonexistent id\");\n\n // When a valid snapshot is queried, there are three possibilities:\n // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never\n // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds\n // to this id is the current one.\n // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the\n // requested id, and its value is the one to return.\n // c) More snapshots were created after the requested one, and the queried value was later modified. There will be\n // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is\n // larger than the requested one.\n //\n // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if\n // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does\n // exactly this.\n\n uint256 index = snapshots.ids.findUpperBound(snapshotId);\n\n if (index == snapshots.ids.length) {\n return (false, 0);\n } else {\n return (true, snapshots.values[index]);\n }\n }\n\n function _updateAccountSnapshot(address account) private {\n _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account));\n }\n\n function _updateTotalSupplySnapshot() private {\n _updateSnapshot(_totalSupplySnapshots, totalSupply());\n }\n\n function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private {\n uint256 currentId = _getCurrentSnapshotId();\n if (_lastSnapshotId(snapshots.ids) < currentId) {\n snapshots.ids.push(currentId);\n snapshots.values.push(currentValue);\n }\n }\n\n function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) {\n if (ids.length == 0) {\n return 0;\n } else {\n return ids[ids.length - 1];\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[46] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-ERC20PermitUpgradeable.sol\";\nimport \"../../../utils/math/MathUpgradeable.sol\";\nimport \"../../../governance/utils/IVotesUpgradeable.sol\";\nimport \"../../../utils/math/SafeCastUpgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\n *\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\n *\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\n *\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\n *\n * _Available since v4.2._\n */\nabstract contract ERC20VotesUpgradeable is Initializable, IVotesUpgradeable, ERC20PermitUpgradeable {\n function __ERC20Votes_init() internal onlyInitializing {\n }\n\n function __ERC20Votes_init_unchained() internal onlyInitializing {\n }\n struct Checkpoint {\n uint32 fromBlock;\n uint224 votes;\n }\n\n bytes32 private constant _DELEGATION_TYPEHASH =\n keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n mapping(address => address) private _delegates;\n mapping(address => Checkpoint[]) private _checkpoints;\n Checkpoint[] private _totalSupplyCheckpoints;\n\n /**\n * @dev Get the `pos`-th checkpoint for `account`.\n */\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\n return _checkpoints[account][pos];\n }\n\n /**\n * @dev Get number of checkpoints for `account`.\n */\n function numCheckpoints(address account) public view virtual returns (uint32) {\n return SafeCastUpgradeable.toUint32(_checkpoints[account].length);\n }\n\n /**\n * @dev Get the address `account` is currently delegating to.\n */\n function delegates(address account) public view virtual override returns (address) {\n return _delegates[account];\n }\n\n /**\n * @dev Gets the current votes balance for `account`\n */\n function getVotes(address account) public view virtual override returns (uint256) {\n uint256 pos = _checkpoints[account].length;\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\n }\n\n /**\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastVotes(address account, uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_checkpoints[account], blockNumber);\n }\n\n /**\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\n * It is but NOT the sum of all the delegated votes!\n *\n * Requirements:\n *\n * - `blockNumber` must have been already mined\n */\n function getPastTotalSupply(uint256 blockNumber) public view virtual override returns (uint256) {\n require(blockNumber < block.number, \"ERC20Votes: block not yet mined\");\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\n }\n\n /**\n * @dev Lookup a value in a list of (sorted) checkpoints.\n */\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\n //\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\n // out of bounds (in which case we're looking too far in the past and the result is 0).\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\n // the same.\n uint256 high = ckpts.length;\n uint256 low = 0;\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n if (ckpts[mid].fromBlock > blockNumber) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n return high == 0 ? 0 : ckpts[high - 1].votes;\n }\n\n /**\n * @dev Delegate votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) public virtual override {\n _delegate(_msgSender(), delegatee);\n }\n\n /**\n * @dev Delegates votes from signer to `delegatee`\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= expiry, \"ERC20Votes: signature expired\");\n address signer = ECDSAUpgradeable.recover(\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\n v,\n r,\n s\n );\n require(nonce == _useNonce(signer), \"ERC20Votes: invalid nonce\");\n _delegate(signer, delegatee);\n }\n\n /**\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\n */\n function _maxSupply() internal view virtual returns (uint224) {\n return type(uint224).max;\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been increased.\n */\n function _mint(address account, uint256 amount) internal virtual override {\n super._mint(account, amount);\n require(totalSupply() <= _maxSupply(), \"ERC20Votes: total supply risks overflowing votes\");\n\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\n }\n\n /**\n * @dev Snapshots the totalSupply after it has been decreased.\n */\n function _burn(address account, uint256 amount) internal virtual override {\n super._burn(account, amount);\n\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\n }\n\n /**\n * @dev Move voting power when tokens are transferred.\n *\n * Emits a {DelegateVotesChanged} event.\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual override {\n super._afterTokenTransfer(from, to, amount);\n\n _moveVotingPower(delegates(from), delegates(to), amount);\n }\n\n /**\n * @dev Change delegation for `delegator` to `delegatee`.\n *\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\n */\n function _delegate(address delegator, address delegatee) internal virtual {\n address currentDelegate = delegates(delegator);\n uint256 delegatorBalance = balanceOf(delegator);\n _delegates[delegator] = delegatee;\n\n emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\n }\n\n function _moveVotingPower(\n address src,\n address dst,\n uint256 amount\n ) private {\n if (src != dst && amount > 0) {\n if (src != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\n emit DelegateVotesChanged(src, oldWeight, newWeight);\n }\n\n if (dst != address(0)) {\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\n }\n }\n }\n\n function _writeCheckpoint(\n Checkpoint[] storage ckpts,\n function(uint256, uint256) view returns (uint256) op,\n uint256 delta\n ) private returns (uint256 oldWeight, uint256 newWeight) {\n uint256 pos = ckpts.length;\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\n newWeight = op(oldWeight, delta);\n\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\n ckpts[pos - 1].votes = SafeCastUpgradeable.toUint224(newWeight);\n } else {\n ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(block.number), votes: SafeCastUpgradeable.toUint224(newWeight)}));\n }\n }\n\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\n return a + b;\n }\n\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\n return a - b;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[47] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20WrapperUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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 public 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 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 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 SafeERC20Upgradeable.safeTransferFrom(underlying, _msgSender(), address(this), amount);\n _mint(account, amount);\n return true;\n }\n\n /**\n * @dev Allow a user to burn a number of wrapped tokens and withdraw the corresponding number of underlying tokens.\n */\n function withdrawTo(address account, uint256 amount) public virtual returns (bool) {\n _burn(_msgSender(), amount);\n SafeERC20Upgradeable.safeTransfer(underlying, account, amount);\n return true;\n }\n\n /**\n * @dev Mint wrapped token to cover any underlyingTokens that would have been transferred by mistake. Internal\n * function that can be exposed with access control if desired.\n */\n function _recover(address account) internal virtual returns (uint256) {\n uint256 value = underlying.balanceOf(address(this)) - totalSupply();\n _mint(account, value);\n return value;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.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(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\nimport \"../extensions/draft-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 function safeTransfer(\n IERC20Upgradeable token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20Upgradeable token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20Upgradeable token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\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 if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.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 *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ArraysUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/MathUpgradeable.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary ArraysUpgradeable {\n /**\n * @dev Searches a sorted `array` and returns the first index that contains\n * a value greater or equal to `element`. If no such index exists (i.e. all\n * values in the array are strictly less than `element`), the array length is\n * returned. Time complexity O(log n).\n *\n * `array` is expected to be sorted in ascending order, and to contain no\n * repeated elements.\n */\n function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n if (array.length == 0) {\n return 0;\n }\n\n uint256 low = 0;\n uint256 high = array.length;\n\n while (low < high) {\n uint256 mid = MathUpgradeable.average(low, high);\n\n // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n // because Math.average rounds down (it does integer division with truncation).\n if (array[mid] > element) {\n high = mid;\n } else {\n low = mid + 1;\n }\n }\n\n // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n if (low > 0 && array[low - 1] == element) {\n return low - 1;\n } else {\n return low;\n }\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary MathUpgradeable {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`.\n // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`.\n // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`.\n // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a\n // good first aproximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1;\n uint256 x = a;\n if (x >> 128 > 0) {\n x >>= 128;\n result <<= 64;\n }\n if (x >> 64 > 0) {\n x >>= 64;\n result <<= 32;\n }\n if (x >> 32 > 0) {\n x >>= 32;\n result <<= 16;\n }\n if (x >> 16 > 0) {\n x >>= 16;\n result <<= 8;\n }\n if (x >> 8 > 0) {\n x >>= 8;\n result <<= 4;\n }\n if (x >> 4 > 0) {\n x >>= 4;\n result <<= 2;\n }\n if (x >> 2 > 0) {\n result <<= 1;\n }\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n uint256 result = sqrt(a);\n if (rounding == Rounding.Up && result * result < a) {\n result += 1;\n }\n return result;\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCastUpgradeable {\n /**\n * @dev Returns the downcasted uint248 from uint256, reverting on\n * overflow (when the input is greater than largest uint248).\n *\n * Counterpart to Solidity's `uint248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toUint248(uint256 value) internal pure returns (uint248) {\n require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return uint248(value);\n }\n\n /**\n * @dev Returns the downcasted uint240 from uint256, reverting on\n * overflow (when the input is greater than largest uint240).\n *\n * Counterpart to Solidity's `uint240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toUint240(uint256 value) internal pure returns (uint240) {\n require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return uint240(value);\n }\n\n /**\n * @dev Returns the downcasted uint232 from uint256, reverting on\n * overflow (when the input is greater than largest uint232).\n *\n * Counterpart to Solidity's `uint232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toUint232(uint256 value) internal pure returns (uint232) {\n require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return uint232(value);\n }\n\n /**\n * @dev Returns the downcasted uint224 from uint256, reverting on\n * overflow (when the input is greater than largest uint224).\n *\n * Counterpart to Solidity's `uint224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.2._\n */\n function toUint224(uint256 value) internal pure returns (uint224) {\n require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return uint224(value);\n }\n\n /**\n * @dev Returns the downcasted uint216 from uint256, reverting on\n * overflow (when the input is greater than largest uint216).\n *\n * Counterpart to Solidity's `uint216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toUint216(uint256 value) internal pure returns (uint216) {\n require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return uint216(value);\n }\n\n /**\n * @dev Returns the downcasted uint208 from uint256, reverting on\n * overflow (when the input is greater than largest uint208).\n *\n * Counterpart to Solidity's `uint208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toUint208(uint256 value) internal pure returns (uint208) {\n require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return uint208(value);\n }\n\n /**\n * @dev Returns the downcasted uint200 from uint256, reverting on\n * overflow (when the input is greater than largest uint200).\n *\n * Counterpart to Solidity's `uint200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toUint200(uint256 value) internal pure returns (uint200) {\n require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return uint200(value);\n }\n\n /**\n * @dev Returns the downcasted uint192 from uint256, reverting on\n * overflow (when the input is greater than largest uint192).\n *\n * Counterpart to Solidity's `uint192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toUint192(uint256 value) internal pure returns (uint192) {\n require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return uint192(value);\n }\n\n /**\n * @dev Returns the downcasted uint184 from uint256, reverting on\n * overflow (when the input is greater than largest uint184).\n *\n * Counterpart to Solidity's `uint184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toUint184(uint256 value) internal pure returns (uint184) {\n require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return uint184(value);\n }\n\n /**\n * @dev Returns the downcasted uint176 from uint256, reverting on\n * overflow (when the input is greater than largest uint176).\n *\n * Counterpart to Solidity's `uint176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toUint176(uint256 value) internal pure returns (uint176) {\n require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return uint176(value);\n }\n\n /**\n * @dev Returns the downcasted uint168 from uint256, reverting on\n * overflow (when the input is greater than largest uint168).\n *\n * Counterpart to Solidity's `uint168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toUint168(uint256 value) internal pure returns (uint168) {\n require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return uint168(value);\n }\n\n /**\n * @dev Returns the downcasted uint160 from uint256, reverting on\n * overflow (when the input is greater than largest uint160).\n *\n * Counterpart to Solidity's `uint160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toUint160(uint256 value) internal pure returns (uint160) {\n require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return uint160(value);\n }\n\n /**\n * @dev Returns the downcasted uint152 from uint256, reverting on\n * overflow (when the input is greater than largest uint152).\n *\n * Counterpart to Solidity's `uint152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toUint152(uint256 value) internal pure returns (uint152) {\n require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return uint152(value);\n }\n\n /**\n * @dev Returns the downcasted uint144 from uint256, reverting on\n * overflow (when the input is greater than largest uint144).\n *\n * Counterpart to Solidity's `uint144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toUint144(uint256 value) internal pure returns (uint144) {\n require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return uint144(value);\n }\n\n /**\n * @dev Returns the downcasted uint136 from uint256, reverting on\n * overflow (when the input is greater than largest uint136).\n *\n * Counterpart to Solidity's `uint136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toUint136(uint256 value) internal pure returns (uint136) {\n require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return uint136(value);\n }\n\n /**\n * @dev Returns the downcasted uint128 from uint256, reverting on\n * overflow (when the input is greater than largest uint128).\n *\n * Counterpart to Solidity's `uint128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v2.5._\n */\n function toUint128(uint256 value) internal pure returns (uint128) {\n require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return uint128(value);\n }\n\n /**\n * @dev Returns the downcasted uint120 from uint256, reverting on\n * overflow (when the input is greater than largest uint120).\n *\n * Counterpart to Solidity's `uint120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toUint120(uint256 value) internal pure returns (uint120) {\n require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return uint120(value);\n }\n\n /**\n * @dev Returns the downcasted uint112 from uint256, reverting on\n * overflow (when the input is greater than largest uint112).\n *\n * Counterpart to Solidity's `uint112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toUint112(uint256 value) internal pure returns (uint112) {\n require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return uint112(value);\n }\n\n /**\n * @dev Returns the downcasted uint104 from uint256, reverting on\n * overflow (when the input is greater than largest uint104).\n *\n * Counterpart to Solidity's `uint104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toUint104(uint256 value) internal pure returns (uint104) {\n require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return uint104(value);\n }\n\n /**\n * @dev Returns the downcasted uint96 from uint256, reverting on\n * overflow (when the input is greater than largest uint96).\n *\n * Counterpart to Solidity's `uint96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.2._\n */\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n /**\n * @dev Returns the downcasted uint88 from uint256, reverting on\n * overflow (when the input is greater than largest uint88).\n *\n * Counterpart to Solidity's `uint88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toUint88(uint256 value) internal pure returns (uint88) {\n require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return uint88(value);\n }\n\n /**\n * @dev Returns the downcasted uint80 from uint256, reverting on\n * overflow (when the input is greater than largest uint80).\n *\n * Counterpart to Solidity's `uint80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toUint80(uint256 value) internal pure returns (uint80) {\n require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return uint80(value);\n }\n\n /**\n * @dev Returns the downcasted uint72 from uint256, reverting on\n * overflow (when the input is greater than largest uint72).\n *\n * Counterpart to Solidity's `uint72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toUint72(uint256 value) internal pure returns (uint72) {\n require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return uint72(value);\n }\n\n /**\n * @dev Returns the downcasted uint64 from uint256, reverting on\n * overflow (when the input is greater than largest uint64).\n *\n * Counterpart to Solidity's `uint64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v2.5._\n */\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n\n /**\n * @dev Returns the downcasted uint56 from uint256, reverting on\n * overflow (when the input is greater than largest uint56).\n *\n * Counterpart to Solidity's `uint56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toUint56(uint256 value) internal pure returns (uint56) {\n require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return uint56(value);\n }\n\n /**\n * @dev Returns the downcasted uint48 from uint256, reverting on\n * overflow (when the input is greater than largest uint48).\n *\n * Counterpart to Solidity's `uint48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toUint48(uint256 value) internal pure returns (uint48) {\n require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return uint48(value);\n }\n\n /**\n * @dev Returns the downcasted uint40 from uint256, reverting on\n * overflow (when the input is greater than largest uint40).\n *\n * Counterpart to Solidity's `uint40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toUint40(uint256 value) internal pure returns (uint40) {\n require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return uint40(value);\n }\n\n /**\n * @dev Returns the downcasted uint32 from uint256, reverting on\n * overflow (when the input is greater than largest uint32).\n *\n * Counterpart to Solidity's `uint32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v2.5._\n */\n function toUint32(uint256 value) internal pure returns (uint32) {\n require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return uint32(value);\n }\n\n /**\n * @dev Returns the downcasted uint24 from uint256, reverting on\n * overflow (when the input is greater than largest uint24).\n *\n * Counterpart to Solidity's `uint24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toUint24(uint256 value) internal pure returns (uint24) {\n require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return uint24(value);\n }\n\n /**\n * @dev Returns the downcasted uint16 from uint256, reverting on\n * overflow (when the input is greater than largest uint16).\n *\n * Counterpart to Solidity's `uint16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v2.5._\n */\n function toUint16(uint256 value) internal pure returns (uint16) {\n require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return uint16(value);\n }\n\n /**\n * @dev Returns the downcasted uint8 from uint256, reverting on\n * overflow (when the input is greater than largest uint8).\n *\n * Counterpart to Solidity's `uint8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v2.5._\n */\n function toUint8(uint256 value) internal pure returns (uint8) {\n require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return uint8(value);\n }\n\n /**\n * @dev Converts a signed int256 into an unsigned uint256.\n *\n * Requirements:\n *\n * - input must be greater than or equal to 0.\n *\n * _Available since v3.0._\n */\n function toUint256(int256 value) internal pure returns (uint256) {\n require(value >= 0, \"SafeCast: value must be positive\");\n return uint256(value);\n }\n\n /**\n * @dev Returns the downcasted int248 from int256, reverting on\n * overflow (when the input is less than smallest int248 or\n * greater than largest int248).\n *\n * Counterpart to Solidity's `int248` operator.\n *\n * Requirements:\n *\n * - input must fit into 248 bits\n *\n * _Available since v4.7._\n */\n function toInt248(int256 value) internal pure returns (int248) {\n require(value >= type(int248).min && value <= type(int248).max, \"SafeCast: value doesn't fit in 248 bits\");\n return int248(value);\n }\n\n /**\n * @dev Returns the downcasted int240 from int256, reverting on\n * overflow (when the input is less than smallest int240 or\n * greater than largest int240).\n *\n * Counterpart to Solidity's `int240` operator.\n *\n * Requirements:\n *\n * - input must fit into 240 bits\n *\n * _Available since v4.7._\n */\n function toInt240(int256 value) internal pure returns (int240) {\n require(value >= type(int240).min && value <= type(int240).max, \"SafeCast: value doesn't fit in 240 bits\");\n return int240(value);\n }\n\n /**\n * @dev Returns the downcasted int232 from int256, reverting on\n * overflow (when the input is less than smallest int232 or\n * greater than largest int232).\n *\n * Counterpart to Solidity's `int232` operator.\n *\n * Requirements:\n *\n * - input must fit into 232 bits\n *\n * _Available since v4.7._\n */\n function toInt232(int256 value) internal pure returns (int232) {\n require(value >= type(int232).min && value <= type(int232).max, \"SafeCast: value doesn't fit in 232 bits\");\n return int232(value);\n }\n\n /**\n * @dev Returns the downcasted int224 from int256, reverting on\n * overflow (when the input is less than smallest int224 or\n * greater than largest int224).\n *\n * Counterpart to Solidity's `int224` operator.\n *\n * Requirements:\n *\n * - input must fit into 224 bits\n *\n * _Available since v4.7._\n */\n function toInt224(int256 value) internal pure returns (int224) {\n require(value >= type(int224).min && value <= type(int224).max, \"SafeCast: value doesn't fit in 224 bits\");\n return int224(value);\n }\n\n /**\n * @dev Returns the downcasted int216 from int256, reverting on\n * overflow (when the input is less than smallest int216 or\n * greater than largest int216).\n *\n * Counterpart to Solidity's `int216` operator.\n *\n * Requirements:\n *\n * - input must fit into 216 bits\n *\n * _Available since v4.7._\n */\n function toInt216(int256 value) internal pure returns (int216) {\n require(value >= type(int216).min && value <= type(int216).max, \"SafeCast: value doesn't fit in 216 bits\");\n return int216(value);\n }\n\n /**\n * @dev Returns the downcasted int208 from int256, reverting on\n * overflow (when the input is less than smallest int208 or\n * greater than largest int208).\n *\n * Counterpart to Solidity's `int208` operator.\n *\n * Requirements:\n *\n * - input must fit into 208 bits\n *\n * _Available since v4.7._\n */\n function toInt208(int256 value) internal pure returns (int208) {\n require(value >= type(int208).min && value <= type(int208).max, \"SafeCast: value doesn't fit in 208 bits\");\n return int208(value);\n }\n\n /**\n * @dev Returns the downcasted int200 from int256, reverting on\n * overflow (when the input is less than smallest int200 or\n * greater than largest int200).\n *\n * Counterpart to Solidity's `int200` operator.\n *\n * Requirements:\n *\n * - input must fit into 200 bits\n *\n * _Available since v4.7._\n */\n function toInt200(int256 value) internal pure returns (int200) {\n require(value >= type(int200).min && value <= type(int200).max, \"SafeCast: value doesn't fit in 200 bits\");\n return int200(value);\n }\n\n /**\n * @dev Returns the downcasted int192 from int256, reverting on\n * overflow (when the input is less than smallest int192 or\n * greater than largest int192).\n *\n * Counterpart to Solidity's `int192` operator.\n *\n * Requirements:\n *\n * - input must fit into 192 bits\n *\n * _Available since v4.7._\n */\n function toInt192(int256 value) internal pure returns (int192) {\n require(value >= type(int192).min && value <= type(int192).max, \"SafeCast: value doesn't fit in 192 bits\");\n return int192(value);\n }\n\n /**\n * @dev Returns the downcasted int184 from int256, reverting on\n * overflow (when the input is less than smallest int184 or\n * greater than largest int184).\n *\n * Counterpart to Solidity's `int184` operator.\n *\n * Requirements:\n *\n * - input must fit into 184 bits\n *\n * _Available since v4.7._\n */\n function toInt184(int256 value) internal pure returns (int184) {\n require(value >= type(int184).min && value <= type(int184).max, \"SafeCast: value doesn't fit in 184 bits\");\n return int184(value);\n }\n\n /**\n * @dev Returns the downcasted int176 from int256, reverting on\n * overflow (when the input is less than smallest int176 or\n * greater than largest int176).\n *\n * Counterpart to Solidity's `int176` operator.\n *\n * Requirements:\n *\n * - input must fit into 176 bits\n *\n * _Available since v4.7._\n */\n function toInt176(int256 value) internal pure returns (int176) {\n require(value >= type(int176).min && value <= type(int176).max, \"SafeCast: value doesn't fit in 176 bits\");\n return int176(value);\n }\n\n /**\n * @dev Returns the downcasted int168 from int256, reverting on\n * overflow (when the input is less than smallest int168 or\n * greater than largest int168).\n *\n * Counterpart to Solidity's `int168` operator.\n *\n * Requirements:\n *\n * - input must fit into 168 bits\n *\n * _Available since v4.7._\n */\n function toInt168(int256 value) internal pure returns (int168) {\n require(value >= type(int168).min && value <= type(int168).max, \"SafeCast: value doesn't fit in 168 bits\");\n return int168(value);\n }\n\n /**\n * @dev Returns the downcasted int160 from int256, reverting on\n * overflow (when the input is less than smallest int160 or\n * greater than largest int160).\n *\n * Counterpart to Solidity's `int160` operator.\n *\n * Requirements:\n *\n * - input must fit into 160 bits\n *\n * _Available since v4.7._\n */\n function toInt160(int256 value) internal pure returns (int160) {\n require(value >= type(int160).min && value <= type(int160).max, \"SafeCast: value doesn't fit in 160 bits\");\n return int160(value);\n }\n\n /**\n * @dev Returns the downcasted int152 from int256, reverting on\n * overflow (when the input is less than smallest int152 or\n * greater than largest int152).\n *\n * Counterpart to Solidity's `int152` operator.\n *\n * Requirements:\n *\n * - input must fit into 152 bits\n *\n * _Available since v4.7._\n */\n function toInt152(int256 value) internal pure returns (int152) {\n require(value >= type(int152).min && value <= type(int152).max, \"SafeCast: value doesn't fit in 152 bits\");\n return int152(value);\n }\n\n /**\n * @dev Returns the downcasted int144 from int256, reverting on\n * overflow (when the input is less than smallest int144 or\n * greater than largest int144).\n *\n * Counterpart to Solidity's `int144` operator.\n *\n * Requirements:\n *\n * - input must fit into 144 bits\n *\n * _Available since v4.7._\n */\n function toInt144(int256 value) internal pure returns (int144) {\n require(value >= type(int144).min && value <= type(int144).max, \"SafeCast: value doesn't fit in 144 bits\");\n return int144(value);\n }\n\n /**\n * @dev Returns the downcasted int136 from int256, reverting on\n * overflow (when the input is less than smallest int136 or\n * greater than largest int136).\n *\n * Counterpart to Solidity's `int136` operator.\n *\n * Requirements:\n *\n * - input must fit into 136 bits\n *\n * _Available since v4.7._\n */\n function toInt136(int256 value) internal pure returns (int136) {\n require(value >= type(int136).min && value <= type(int136).max, \"SafeCast: value doesn't fit in 136 bits\");\n return int136(value);\n }\n\n /**\n * @dev Returns the downcasted int128 from int256, reverting on\n * overflow (when the input is less than smallest int128 or\n * greater than largest int128).\n *\n * Counterpart to Solidity's `int128` operator.\n *\n * Requirements:\n *\n * - input must fit into 128 bits\n *\n * _Available since v3.1._\n */\n function toInt128(int256 value) internal pure returns (int128) {\n require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n return int128(value);\n }\n\n /**\n * @dev Returns the downcasted int120 from int256, reverting on\n * overflow (when the input is less than smallest int120 or\n * greater than largest int120).\n *\n * Counterpart to Solidity's `int120` operator.\n *\n * Requirements:\n *\n * - input must fit into 120 bits\n *\n * _Available since v4.7._\n */\n function toInt120(int256 value) internal pure returns (int120) {\n require(value >= type(int120).min && value <= type(int120).max, \"SafeCast: value doesn't fit in 120 bits\");\n return int120(value);\n }\n\n /**\n * @dev Returns the downcasted int112 from int256, reverting on\n * overflow (when the input is less than smallest int112 or\n * greater than largest int112).\n *\n * Counterpart to Solidity's `int112` operator.\n *\n * Requirements:\n *\n * - input must fit into 112 bits\n *\n * _Available since v4.7._\n */\n function toInt112(int256 value) internal pure returns (int112) {\n require(value >= type(int112).min && value <= type(int112).max, \"SafeCast: value doesn't fit in 112 bits\");\n return int112(value);\n }\n\n /**\n * @dev Returns the downcasted int104 from int256, reverting on\n * overflow (when the input is less than smallest int104 or\n * greater than largest int104).\n *\n * Counterpart to Solidity's `int104` operator.\n *\n * Requirements:\n *\n * - input must fit into 104 bits\n *\n * _Available since v4.7._\n */\n function toInt104(int256 value) internal pure returns (int104) {\n require(value >= type(int104).min && value <= type(int104).max, \"SafeCast: value doesn't fit in 104 bits\");\n return int104(value);\n }\n\n /**\n * @dev Returns the downcasted int96 from int256, reverting on\n * overflow (when the input is less than smallest int96 or\n * greater than largest int96).\n *\n * Counterpart to Solidity's `int96` operator.\n *\n * Requirements:\n *\n * - input must fit into 96 bits\n *\n * _Available since v4.7._\n */\n function toInt96(int256 value) internal pure returns (int96) {\n require(value >= type(int96).min && value <= type(int96).max, \"SafeCast: value doesn't fit in 96 bits\");\n return int96(value);\n }\n\n /**\n * @dev Returns the downcasted int88 from int256, reverting on\n * overflow (when the input is less than smallest int88 or\n * greater than largest int88).\n *\n * Counterpart to Solidity's `int88` operator.\n *\n * Requirements:\n *\n * - input must fit into 88 bits\n *\n * _Available since v4.7._\n */\n function toInt88(int256 value) internal pure returns (int88) {\n require(value >= type(int88).min && value <= type(int88).max, \"SafeCast: value doesn't fit in 88 bits\");\n return int88(value);\n }\n\n /**\n * @dev Returns the downcasted int80 from int256, reverting on\n * overflow (when the input is less than smallest int80 or\n * greater than largest int80).\n *\n * Counterpart to Solidity's `int80` operator.\n *\n * Requirements:\n *\n * - input must fit into 80 bits\n *\n * _Available since v4.7._\n */\n function toInt80(int256 value) internal pure returns (int80) {\n require(value >= type(int80).min && value <= type(int80).max, \"SafeCast: value doesn't fit in 80 bits\");\n return int80(value);\n }\n\n /**\n * @dev Returns the downcasted int72 from int256, reverting on\n * overflow (when the input is less than smallest int72 or\n * greater than largest int72).\n *\n * Counterpart to Solidity's `int72` operator.\n *\n * Requirements:\n *\n * - input must fit into 72 bits\n *\n * _Available since v4.7._\n */\n function toInt72(int256 value) internal pure returns (int72) {\n require(value >= type(int72).min && value <= type(int72).max, \"SafeCast: value doesn't fit in 72 bits\");\n return int72(value);\n }\n\n /**\n * @dev Returns the downcasted int64 from int256, reverting on\n * overflow (when the input is less than smallest int64 or\n * greater than largest int64).\n *\n * Counterpart to Solidity's `int64` operator.\n *\n * Requirements:\n *\n * - input must fit into 64 bits\n *\n * _Available since v3.1._\n */\n function toInt64(int256 value) internal pure returns (int64) {\n require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n return int64(value);\n }\n\n /**\n * @dev Returns the downcasted int56 from int256, reverting on\n * overflow (when the input is less than smallest int56 or\n * greater than largest int56).\n *\n * Counterpart to Solidity's `int56` operator.\n *\n * Requirements:\n *\n * - input must fit into 56 bits\n *\n * _Available since v4.7._\n */\n function toInt56(int256 value) internal pure returns (int56) {\n require(value >= type(int56).min && value <= type(int56).max, \"SafeCast: value doesn't fit in 56 bits\");\n return int56(value);\n }\n\n /**\n * @dev Returns the downcasted int48 from int256, reverting on\n * overflow (when the input is less than smallest int48 or\n * greater than largest int48).\n *\n * Counterpart to Solidity's `int48` operator.\n *\n * Requirements:\n *\n * - input must fit into 48 bits\n *\n * _Available since v4.7._\n */\n function toInt48(int256 value) internal pure returns (int48) {\n require(value >= type(int48).min && value <= type(int48).max, \"SafeCast: value doesn't fit in 48 bits\");\n return int48(value);\n }\n\n /**\n * @dev Returns the downcasted int40 from int256, reverting on\n * overflow (when the input is less than smallest int40 or\n * greater than largest int40).\n *\n * Counterpart to Solidity's `int40` operator.\n *\n * Requirements:\n *\n * - input must fit into 40 bits\n *\n * _Available since v4.7._\n */\n function toInt40(int256 value) internal pure returns (int40) {\n require(value >= type(int40).min && value <= type(int40).max, \"SafeCast: value doesn't fit in 40 bits\");\n return int40(value);\n }\n\n /**\n * @dev Returns the downcasted int32 from int256, reverting on\n * overflow (when the input is less than smallest int32 or\n * greater than largest int32).\n *\n * Counterpart to Solidity's `int32` operator.\n *\n * Requirements:\n *\n * - input must fit into 32 bits\n *\n * _Available since v3.1._\n */\n function toInt32(int256 value) internal pure returns (int32) {\n require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n return int32(value);\n }\n\n /**\n * @dev Returns the downcasted int24 from int256, reverting on\n * overflow (when the input is less than smallest int24 or\n * greater than largest int24).\n *\n * Counterpart to Solidity's `int24` operator.\n *\n * Requirements:\n *\n * - input must fit into 24 bits\n *\n * _Available since v4.7._\n */\n function toInt24(int256 value) internal pure returns (int24) {\n require(value >= type(int24).min && value <= type(int24).max, \"SafeCast: value doesn't fit in 24 bits\");\n return int24(value);\n }\n\n /**\n * @dev Returns the downcasted int16 from int256, reverting on\n * overflow (when the input is less than smallest int16 or\n * greater than largest int16).\n *\n * Counterpart to Solidity's `int16` operator.\n *\n * Requirements:\n *\n * - input must fit into 16 bits\n *\n * _Available since v3.1._\n */\n function toInt16(int256 value) internal pure returns (int16) {\n require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n return int16(value);\n }\n\n /**\n * @dev Returns the downcasted int8 from int256, reverting on\n * overflow (when the input is less than smallest int8 or\n * greater than largest int8).\n *\n * Counterpart to Solidity's `int8` operator.\n *\n * Requirements:\n *\n * - input must fit into 8 bits\n *\n * _Available since v3.1._\n */\n function toInt8(int256 value) internal pure returns (int8) {\n require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n return int8(value);\n }\n\n /**\n * @dev Converts an unsigned uint256 into a signed int256.\n *\n * Requirements:\n *\n * - input must be less than or equal to maxInt256.\n *\n * _Available since v3.0._\n */\n function toInt256(uint256 value) internal pure returns (int256) {\n // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n return int256(value);\n }\n}\n" - }, - "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "@openzeppelin/contracts/governance/utils/IVotes.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol)\npragma solidity ^0.8.0;\n\n/**\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\n *\n * _Available since v4.5._\n */\ninterface IVotes {\n /**\n * @dev Emitted when an account changes their delegate.\n */\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n /**\n * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.\n */\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\n\n /**\n * @dev Returns the current amount of votes that `account` has.\n */\n function getVotes(address account) external view returns (uint256);\n\n /**\n * @dev Returns the amount of votes that `account` had at the end of a past block (`blockNumber`).\n */\n function getPastVotes(address account, uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the total supply of votes available at the end of a past block (`blockNumber`).\n *\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\n * vote.\n */\n function getPastTotalSupply(uint256 blockNumber) external view returns (uint256);\n\n /**\n * @dev Returns the delegate that `account` has chosen.\n */\n function delegates(address account) external view returns (address);\n\n /**\n * @dev Delegates votes from the sender to `delegatee`.\n */\n function delegate(address delegatee) external;\n\n /**\n * @dev Delegates votes from signer to `delegatee`.\n */\n function delegateBySig(\n address delegatee,\n uint256 nonce,\n uint256 expiry,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n}\n" - }, - "@openzeppelin/contracts/interfaces/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/introspection/IERC165.sol\";\n" - }, - "@openzeppelin/contracts/token/ERC20/ERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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 }\n _balances[to] += amount;\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 _balances[account] += amount;\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 }\n _totalSupply -= amount;\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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address owner,\n address spender,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) 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(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/IERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" - }, - "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) 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(\n IERC20 token,\n address spender,\n uint256 value\n ) 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 function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" - }, - "@openzeppelin/contracts/token/ERC721/ERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _owners[tokenId];\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner nor approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner nor approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _owners[tokenId] != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(\n address to,\n uint256 tokenId,\n bytes memory data\n ) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId);\n\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId);\n\n // Clear approvals\n _approve(address(0), tokenId);\n\n _balances[owner] -= 1;\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId);\n\n // Clear approvals from the previous owner\n _approve(address(0), tokenId);\n\n _balances[from] -= 1;\n _balances[to] += 1;\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(\n address owner,\n address operator,\n bool approved\n ) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting\n * and burning.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be\n * transferred to `to`.\n * - When `from` is zero, `tokenId` will be minted for `to`.\n * - When `to` is zero, ``from``'s `tokenId` 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(\n address from,\n address to,\n uint256 tokenId\n ) 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.\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(\n address from,\n address to,\n uint256 tokenId\n ) internal virtual {}\n}\n" - }, - "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" - }, - "@openzeppelin/contracts/token/ERC721/IERC721.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" - }, - "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" - }, - "@openzeppelin/contracts/utils/Address.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n address target,\n bytes memory data,\n uint256 value\n ) 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 require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(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 require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(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 require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason 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 // 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}\n" - }, - "@openzeppelin/contracts/utils/Context.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/introspection/ERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC165.sol\";\n\n/**\n * @dev Storage based implementation of the {IERC165} interface.\n *\n * Contracts may inherit from this and call {_registerInterface} to declare\n * their support of an interface.\n */\nabstract contract ERC165Storage is ERC165 {\n /**\n * @dev Mapping of interface ids to whether or not it's supported.\n */\n mapping(bytes4 => bool) private _supportedInterfaces;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];\n }\n\n /**\n * @dev Registers the contract as an implementer of the interface defined by\n * `interfaceId`. Support of the actual ERC165 interface is automatic and\n * registering its interface id is not required.\n *\n * See {IERC165-supportsInterface}.\n *\n * Requirements:\n *\n * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n */\n function _registerInterface(bytes4 interfaceId) internal virtual {\n require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n _supportedInterfaces[interfaceId] = true;\n }\n}\n" - }, - "@openzeppelin/contracts/utils/introspection/IERC165.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" - }, - "@openzeppelin/contracts/utils/Strings.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" - }, - "@prb/math/src/Common.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n// Common.sol\n//\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\n// always operate with SD59x18 and UD60x18 numbers.\n\n/*//////////////////////////////////////////////////////////////////////////\n CUSTOM ERRORS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\n\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\n\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\nerror PRBMath_MulDivSigned_InputTooSmall();\n\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\n\n/*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @dev The maximum value a uint128 number can have.\nuint128 constant MAX_UINT128 = type(uint128).max;\n\n/// @dev The maximum value a uint40 number can have.\nuint40 constant MAX_UINT40 = type(uint40).max;\n\n/// @dev The unit number, which the decimal precision of the fixed-point types.\nuint256 constant UNIT = 1e18;\n\n/// @dev The unit number inverted mod 2^256.\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\n\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\n/// bit in the binary representation of `UNIT`.\nuint256 constant UNIT_LPOTD = 262144;\n\n/*//////////////////////////////////////////////////////////////////////////\n FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(uint256 x) pure returns (uint256 result) {\n unchecked {\n // Start from 0.5 in the 192.64-bit fixed-point format.\n result = 0x800000000000000000000000000000000000000000000000;\n\n // The following logic multiplies the result by $\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\n //\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\n // we know that `x & 0xFF` is also 1.\n if (x & 0xFF00000000000000 > 0) {\n if (x & 0x8000000000000000 > 0) {\n result = (result * 0x16A09E667F3BCC909) >> 64;\n }\n if (x & 0x4000000000000000 > 0) {\n result = (result * 0x1306FE0A31B7152DF) >> 64;\n }\n if (x & 0x2000000000000000 > 0) {\n result = (result * 0x1172B83C7D517ADCE) >> 64;\n }\n if (x & 0x1000000000000000 > 0) {\n result = (result * 0x10B5586CF9890F62A) >> 64;\n }\n if (x & 0x800000000000000 > 0) {\n result = (result * 0x1059B0D31585743AE) >> 64;\n }\n if (x & 0x400000000000000 > 0) {\n result = (result * 0x102C9A3E778060EE7) >> 64;\n }\n if (x & 0x200000000000000 > 0) {\n result = (result * 0x10163DA9FB33356D8) >> 64;\n }\n if (x & 0x100000000000000 > 0) {\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\n }\n }\n\n if (x & 0xFF000000000000 > 0) {\n if (x & 0x80000000000000 > 0) {\n result = (result * 0x10058C86DA1C09EA2) >> 64;\n }\n if (x & 0x40000000000000 > 0) {\n result = (result * 0x1002C605E2E8CEC50) >> 64;\n }\n if (x & 0x20000000000000 > 0) {\n result = (result * 0x100162F3904051FA1) >> 64;\n }\n if (x & 0x10000000000000 > 0) {\n result = (result * 0x1000B175EFFDC76BA) >> 64;\n }\n if (x & 0x8000000000000 > 0) {\n result = (result * 0x100058BA01FB9F96D) >> 64;\n }\n if (x & 0x4000000000000 > 0) {\n result = (result * 0x10002C5CC37DA9492) >> 64;\n }\n if (x & 0x2000000000000 > 0) {\n result = (result * 0x1000162E525EE0547) >> 64;\n }\n if (x & 0x1000000000000 > 0) {\n result = (result * 0x10000B17255775C04) >> 64;\n }\n }\n\n if (x & 0xFF0000000000 > 0) {\n if (x & 0x800000000000 > 0) {\n result = (result * 0x1000058B91B5BC9AE) >> 64;\n }\n if (x & 0x400000000000 > 0) {\n result = (result * 0x100002C5C89D5EC6D) >> 64;\n }\n if (x & 0x200000000000 > 0) {\n result = (result * 0x10000162E43F4F831) >> 64;\n }\n if (x & 0x100000000000 > 0) {\n result = (result * 0x100000B1721BCFC9A) >> 64;\n }\n if (x & 0x80000000000 > 0) {\n result = (result * 0x10000058B90CF1E6E) >> 64;\n }\n if (x & 0x40000000000 > 0) {\n result = (result * 0x1000002C5C863B73F) >> 64;\n }\n if (x & 0x20000000000 > 0) {\n result = (result * 0x100000162E430E5A2) >> 64;\n }\n if (x & 0x10000000000 > 0) {\n result = (result * 0x1000000B172183551) >> 64;\n }\n }\n\n if (x & 0xFF00000000 > 0) {\n if (x & 0x8000000000 > 0) {\n result = (result * 0x100000058B90C0B49) >> 64;\n }\n if (x & 0x4000000000 > 0) {\n result = (result * 0x10000002C5C8601CC) >> 64;\n }\n if (x & 0x2000000000 > 0) {\n result = (result * 0x1000000162E42FFF0) >> 64;\n }\n if (x & 0x1000000000 > 0) {\n result = (result * 0x10000000B17217FBB) >> 64;\n }\n if (x & 0x800000000 > 0) {\n result = (result * 0x1000000058B90BFCE) >> 64;\n }\n if (x & 0x400000000 > 0) {\n result = (result * 0x100000002C5C85FE3) >> 64;\n }\n if (x & 0x200000000 > 0) {\n result = (result * 0x10000000162E42FF1) >> 64;\n }\n if (x & 0x100000000 > 0) {\n result = (result * 0x100000000B17217F8) >> 64;\n }\n }\n\n if (x & 0xFF000000 > 0) {\n if (x & 0x80000000 > 0) {\n result = (result * 0x10000000058B90BFC) >> 64;\n }\n if (x & 0x40000000 > 0) {\n result = (result * 0x1000000002C5C85FE) >> 64;\n }\n if (x & 0x20000000 > 0) {\n result = (result * 0x100000000162E42FF) >> 64;\n }\n if (x & 0x10000000 > 0) {\n result = (result * 0x1000000000B17217F) >> 64;\n }\n if (x & 0x8000000 > 0) {\n result = (result * 0x100000000058B90C0) >> 64;\n }\n if (x & 0x4000000 > 0) {\n result = (result * 0x10000000002C5C860) >> 64;\n }\n if (x & 0x2000000 > 0) {\n result = (result * 0x1000000000162E430) >> 64;\n }\n if (x & 0x1000000 > 0) {\n result = (result * 0x10000000000B17218) >> 64;\n }\n }\n\n if (x & 0xFF0000 > 0) {\n if (x & 0x800000 > 0) {\n result = (result * 0x1000000000058B90C) >> 64;\n }\n if (x & 0x400000 > 0) {\n result = (result * 0x100000000002C5C86) >> 64;\n }\n if (x & 0x200000 > 0) {\n result = (result * 0x10000000000162E43) >> 64;\n }\n if (x & 0x100000 > 0) {\n result = (result * 0x100000000000B1721) >> 64;\n }\n if (x & 0x80000 > 0) {\n result = (result * 0x10000000000058B91) >> 64;\n }\n if (x & 0x40000 > 0) {\n result = (result * 0x1000000000002C5C8) >> 64;\n }\n if (x & 0x20000 > 0) {\n result = (result * 0x100000000000162E4) >> 64;\n }\n if (x & 0x10000 > 0) {\n result = (result * 0x1000000000000B172) >> 64;\n }\n }\n\n if (x & 0xFF00 > 0) {\n if (x & 0x8000 > 0) {\n result = (result * 0x100000000000058B9) >> 64;\n }\n if (x & 0x4000 > 0) {\n result = (result * 0x10000000000002C5D) >> 64;\n }\n if (x & 0x2000 > 0) {\n result = (result * 0x1000000000000162E) >> 64;\n }\n if (x & 0x1000 > 0) {\n result = (result * 0x10000000000000B17) >> 64;\n }\n if (x & 0x800 > 0) {\n result = (result * 0x1000000000000058C) >> 64;\n }\n if (x & 0x400 > 0) {\n result = (result * 0x100000000000002C6) >> 64;\n }\n if (x & 0x200 > 0) {\n result = (result * 0x10000000000000163) >> 64;\n }\n if (x & 0x100 > 0) {\n result = (result * 0x100000000000000B1) >> 64;\n }\n }\n\n if (x & 0xFF > 0) {\n if (x & 0x80 > 0) {\n result = (result * 0x10000000000000059) >> 64;\n }\n if (x & 0x40 > 0) {\n result = (result * 0x1000000000000002C) >> 64;\n }\n if (x & 0x20 > 0) {\n result = (result * 0x10000000000000016) >> 64;\n }\n if (x & 0x10 > 0) {\n result = (result * 0x1000000000000000B) >> 64;\n }\n if (x & 0x8 > 0) {\n result = (result * 0x10000000000000006) >> 64;\n }\n if (x & 0x4 > 0) {\n result = (result * 0x10000000000000003) >> 64;\n }\n if (x & 0x2 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n if (x & 0x1 > 0) {\n result = (result * 0x10000000000000001) >> 64;\n }\n }\n\n // In the code snippet below, two operations are executed simultaneously:\n //\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\n //\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\n // integer part, $2^n$.\n result *= UNIT;\n result >>= (191 - (x >> 64));\n }\n}\n\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\n///\n/// @dev See the note on \"msb\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\n///\n/// Each step in this implementation is equivalent to this high-level code:\n///\n/// ```solidity\n/// if (x >= 2 ** 128) {\n/// x >>= 128;\n/// result += 128;\n/// }\n/// ```\n///\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\n///\n/// The Yul instructions used below are:\n///\n/// - \"gt\" is \"greater than\"\n/// - \"or\" is the OR bitwise operator\n/// - \"shl\" is \"shift left\"\n/// - \"shr\" is \"shift right\"\n///\n/// @param x The uint256 number for which to find the index of the most significant bit.\n/// @return result The index of the most significant bit as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction msb(uint256 x) pure returns (uint256 result) {\n // 2^128\n assembly (\"memory-safe\") {\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^64\n assembly (\"memory-safe\") {\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^32\n assembly (\"memory-safe\") {\n let factor := shl(5, gt(x, 0xFFFFFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^16\n assembly (\"memory-safe\") {\n let factor := shl(4, gt(x, 0xFFFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^8\n assembly (\"memory-safe\") {\n let factor := shl(3, gt(x, 0xFF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^4\n assembly (\"memory-safe\") {\n let factor := shl(2, gt(x, 0xF))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^2\n assembly (\"memory-safe\") {\n let factor := shl(1, gt(x, 0x3))\n x := shr(factor, x)\n result := or(result, factor)\n }\n // 2^1\n // No need to shift x any more.\n assembly (\"memory-safe\") {\n let factor := gt(x, 0x1)\n result := or(result, factor)\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - The denominator must not be zero.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as a uint256.\n/// @param y The multiplier as a uint256.\n/// @param denominator The divisor as a uint256.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n unchecked {\n return prod0 / denominator;\n }\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n if (prod1 >= denominator) {\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\n }\n\n ////////////////////////////////////////////////////////////////////////////\n // 512 by 256 division\n ////////////////////////////////////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly (\"memory-safe\") {\n // Compute remainder using the mulmod Yul instruction.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512-bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n unchecked {\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\n uint256 lpotdod = denominator & (~denominator + 1);\n uint256 flippedLpotdod;\n\n assembly (\"memory-safe\") {\n // Factor powers of two out of denominator.\n denominator := div(denominator, lpotdod)\n\n // Divide [prod1 prod0] by lpotdod.\n prod0 := div(prod0, lpotdod)\n\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * flippedLpotdod;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n }\n}\n\n/// @notice Calculates x*y÷1e18 with 512-bit precision.\n///\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\n///\n/// Notes:\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\n/// - The result is rounded toward zero.\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\n///\n/// $$\n/// \\begin{cases}\n/// x * y = MAX\\_UINT256 * UNIT \\\\\n/// (x * y) \\% UNIT \\geq \\frac{UNIT}{2}\n/// \\end{cases}\n/// $$\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - The result must fit in uint256.\n///\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\n uint256 prod0;\n uint256 prod1;\n assembly (\"memory-safe\") {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n if (prod1 == 0) {\n unchecked {\n return prod0 / UNIT;\n }\n }\n\n if (prod1 >= UNIT) {\n revert PRBMath_MulDiv18_Overflow(x, y);\n }\n\n uint256 remainder;\n assembly (\"memory-safe\") {\n remainder := mulmod(x, y, UNIT)\n result :=\n mul(\n or(\n div(sub(prod0, remainder), UNIT_LPOTD),\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\n ),\n UNIT_INVERSE\n )\n }\n}\n\n/// @notice Calculates x*y÷denominator with 512-bit precision.\n///\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {mulDiv}.\n/// - None of the inputs can be `type(int256).min`.\n/// - The result must fit in int256.\n///\n/// @param x The multiplicand as an int256.\n/// @param y The multiplier as an int256.\n/// @param denominator The divisor as an int256.\n/// @return result The result as an int256.\n/// @custom:smtchecker abstract-function-nondet\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\n revert PRBMath_MulDivSigned_InputTooSmall();\n }\n\n // Get hold of the absolute values of x, y and the denominator.\n uint256 xAbs;\n uint256 yAbs;\n uint256 dAbs;\n unchecked {\n xAbs = x < 0 ? uint256(-x) : uint256(x);\n yAbs = y < 0 ? uint256(-y) : uint256(y);\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\n }\n\n // Compute the absolute value of x*y÷denominator. The result must fit in int256.\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\n if (resultAbs > uint256(type(int256).max)) {\n revert PRBMath_MulDivSigned_Overflow(x, y);\n }\n\n // Get the signs of x, y and the denominator.\n uint256 sx;\n uint256 sy;\n uint256 sd;\n assembly (\"memory-safe\") {\n // \"sgt\" is the \"signed greater than\" assembly instruction and \"sub(0,1)\" is -1 in two's complement.\n sx := sgt(x, sub(0, 1))\n sy := sgt(y, sub(0, 1))\n sd := sgt(denominator, sub(0, 1))\n }\n\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\n // If there are, the result should be negative. Otherwise, it should be positive.\n unchecked {\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - If x is not a perfect square, the result is rounded down.\n/// - Credits to OpenZeppelin for the explanations in comments below.\n///\n/// @param x The uint256 number for which to calculate the square root.\n/// @return result The result as a uint256.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(uint256 x) pure returns (uint256 result) {\n if (x == 0) {\n return 0;\n }\n\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\n //\n // We know that the \"msb\" (most significant bit) of x is a power of 2 such that we have:\n //\n // $$\n // msb(x) <= x <= 2*msb(x)$\n // $$\n //\n // We write $msb(x)$ as $2^k$, and we get:\n //\n // $$\n // k = log_2(x)\n // $$\n //\n // Thus, we can write the initial inequality as:\n //\n // $$\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\n // $$\n //\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\n uint256 xAux = uint256(x);\n result = 1;\n if (xAux >= 2 ** 128) {\n xAux >>= 128;\n result <<= 64;\n }\n if (xAux >= 2 ** 64) {\n xAux >>= 64;\n result <<= 32;\n }\n if (xAux >= 2 ** 32) {\n xAux >>= 32;\n result <<= 16;\n }\n if (xAux >= 2 ** 16) {\n xAux >>= 16;\n result <<= 8;\n }\n if (xAux >= 2 ** 8) {\n xAux >>= 8;\n result <<= 4;\n }\n if (xAux >= 2 ** 4) {\n xAux >>= 4;\n result <<= 2;\n }\n if (xAux >= 2 ** 2) {\n result <<= 1;\n }\n\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\n // precision into the expected uint128 result.\n unchecked {\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n result = (result + x / result) >> 1;\n\n // If x is not a perfect square, round the result toward zero.\n uint256 roundedResult = x / result;\n if (result >= roundedResult) {\n result = roundedResult;\n }\n }\n}\n" - }, - "@prb/math/src/sd1x18/Casting.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as CastingErrors;\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD1x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\n}\n\n/// @notice Casts an SD1x18 number into UD2x18.\n/// - x must be positive.\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\n }\n result = UD2x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\n }\n result = uint256(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\n }\n result = uint128(uint64(xInt));\n}\n\n/// @notice Casts an SD1x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\n int64 xInt = SD1x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\n }\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\n }\n result = uint40(uint64(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n\n/// @notice Unwraps an SD1x18 number into int64.\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\n result = SD1x18.unwrap(x);\n}\n\n/// @notice Wraps an int64 number into SD1x18.\nfunction wrap(int64 x) pure returns (SD1x18 result) {\n result = SD1x18.wrap(x);\n}\n" - }, - "@prb/math/src/sd1x18/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as an SD1x18 number.\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\n\n/// @dev The maximum value an SD1x18 number can have.\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\n\n/// @dev PI as an SD1x18 number.\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD1x18.\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\nint64 constant uUNIT = 1e18;\n" - }, - "@prb/math/src/sd1x18/Errors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD1x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\n\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\n" - }, - "@prb/math/src/sd1x18/ValueType.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype SD1x18 is int64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD59x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD1x18 global;\n" - }, - "@prb/math/src/sd59x18/Casting.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Casts an SD59x18 number into int256.\n/// @dev This is basically a functional alias for {unwrap}.\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Casts an SD59x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be greater than or equal to `uMIN_SD1x18`.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < uMIN_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\n }\n if (xInt > uMAX_SD1x18) {\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xInt));\n}\n\n/// @notice Casts an SD59x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\n }\n if (xInt > int256(uint256(uMAX_UD2x18))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(uint256(xInt)));\n}\n\n/// @notice Casts an SD59x18 number into UD60x18.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\n }\n result = UD60x18.wrap(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint256.\n/// @dev Requirements:\n/// - x must be positive.\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\n }\n result = uint256(xInt);\n}\n\n/// @notice Casts an SD59x18 number into uint128.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `uMAX_UINT128`.\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT128))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\n }\n result = uint128(uint256(xInt));\n}\n\n/// @notice Casts an SD59x18 number into uint40.\n/// @dev Requirements:\n/// - x must be positive.\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\n int256 xInt = SD59x18.unwrap(x);\n if (xInt < 0) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\n }\n if (xInt > int256(uint256(MAX_UINT40))) {\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\n }\n result = uint40(uint256(xInt));\n}\n\n/// @notice Alias for {wrap}.\nfunction sd(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n\n/// @notice Unwraps an SD59x18 number into int256.\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\n result = SD59x18.unwrap(x);\n}\n\n/// @notice Wraps an int256 number into SD59x18.\nfunction wrap(int256 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(x);\n}\n" - }, - "@prb/math/src/sd59x18/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as an SD59x18 number.\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp}.\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\n\n/// @dev The maximum input permitted in {exp2}.\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Any value less than this returns 0 in {exp2}.\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\n\n/// @dev Half the UNIT number.\nint256 constant uHALF_UNIT = 0.5e18;\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as an SD59x18 number.\nint256 constant uLOG2_10 = 3_321928094887362347;\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as an SD59x18 number.\nint256 constant uLOG2_E = 1_442695040888963407;\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\n\n/// @dev The maximum value an SD59x18 number can have.\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\n\n/// @dev The maximum whole value an SD59x18 number can have.\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\n\n/// @dev The minimum value an SD59x18 number can have.\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\n\n/// @dev The minimum whole value an SD59x18 number can have.\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\n\n/// @dev PI as an SD59x18 number.\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of SD59x18.\nint256 constant uUNIT = 1e18;\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\n\n/// @dev The unit number squared.\nint256 constant uUNIT_SQUARED = 1e36;\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as an SD59x18 number.\nSD59x18 constant ZERO = SD59x18.wrap(0);\n" - }, - "@prb/math/src/sd59x18/Errors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\nerror PRBMath_SD59x18_Abs_MinSD59x18();\n\n/// @notice Thrown when ceiling a number overflows SD59x18.\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\n\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Div_InputTooSmall();\n\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\n\n/// @notice Thrown when flooring a number underflows SD59x18.\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\n\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\nerror PRBMath_SD59x18_Mul_InputTooSmall();\n\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\n\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\n\n/// @notice Thrown when taking the square root of a negative number.\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\n\n/// @notice Thrown when the calculating the square root overflows SD59x18.\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\n" - }, - "@prb/math/src/sd59x18/Helpers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n return wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal (=) operation in the SD59x18 type.\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the SD59x18 type.\nfunction isZero(SD59x18 x) pure returns (bool result) {\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(-x.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\n unchecked {\n result = wrap(-x.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" - }, - "@prb/math/src/sd59x18/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uEXP_MIN_THRESHOLD,\n uEXP2_MIN_THRESHOLD,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_SD59x18,\n uMAX_WHOLE_SD59x18,\n uMIN_SD59x18,\n uMIN_WHOLE_SD59x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { wrap } from \"./Helpers.sol\";\nimport { SD59x18 } from \"./ValueType.sol\";\n\n/// @notice Calculates the absolute value of x.\n///\n/// @dev Requirements:\n/// - x must be greater than `MIN_SD59x18`.\n///\n/// @param x The SD59x18 number for which to calculate the absolute value.\n/// @param result The absolute value of x as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\n }\n result = xInt < 0 ? wrap(-xInt) : x;\n}\n\n/// @notice Calculates the arithmetic average of x and y.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The arithmetic average as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n unchecked {\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\n int256 sum = (xInt >> 1) + (yInt >> 1);\n\n if (sum < 0) {\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\n assembly (\"memory-safe\") {\n result := add(sum, and(or(xInt, yInt), 1))\n }\n } else {\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\n result = wrap(sum + (xInt & yInt & 1));\n }\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt > uMAX_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt > 0) {\n resultInt += uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\n///\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\n/// values separately.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The denominator must not be zero.\n/// - The result must fit in SD59x18.\n///\n/// @param x The numerator as an SD59x18 number.\n/// @param y The denominator as an SD59x18 number.\n/// @param result The quotient as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*UNIT÷y). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}.\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n\n // Any input less than the threshold returns zero.\n // This check also prevents an overflow for very small numbers.\n if (xInt < uEXP_MIN_THRESHOLD) {\n return ZERO;\n }\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xInt > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n int256 doubleUnitProduct = xInt * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\n///\n/// $$\n/// 2^{-x} = \\frac{1}{2^x}\n/// $$\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\n///\n/// Notes:\n/// - If x is less than -59_794705707972522261, the result is zero.\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in SD59x18.\n///\n/// @param x The exponent as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n // The inverse of any number less than the threshold is truncated to zero.\n if (xInt < uEXP2_MIN_THRESHOLD) {\n return ZERO;\n }\n\n unchecked {\n // Inline the fixed-point inversion to save gas.\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\n }\n } else {\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xInt > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\n }\n\n unchecked {\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\n\n // It is safe to cast the result to int256 due to the checks above.\n result = wrap(int256(Common.exp2(x_192x64)));\n }\n }\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n///\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\n///\n/// @param x The SD59x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < uMIN_WHOLE_SD59x18) {\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\n }\n\n int256 remainder = xInt % uUNIT;\n if (remainder == 0) {\n result = x;\n } else {\n unchecked {\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\n int256 resultInt = xInt - remainder;\n if (xInt < 0) {\n resultInt -= uUNIT;\n }\n result = wrap(resultInt);\n }\n }\n}\n\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\n/// of the radix point for negative numbers.\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\n/// @param x The SD59x18 number to get the fractional part of.\n/// @param result The fractional part of x as an SD59x18 number.\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(x.unwrap() % uUNIT);\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x * y must fit in SD59x18.\n/// - x * y must not be negative, since complex numbers are not supported.\n///\n/// @param x The first operand as an SD59x18 number.\n/// @param y The second operand as an SD59x18 number.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == 0 || yInt == 0) {\n return ZERO;\n }\n\n unchecked {\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\n int256 xyInt = xInt * yInt;\n if (xyInt / xInt != yInt) {\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\n }\n\n // The product must not be negative, since complex numbers are not supported.\n if (xyInt < 0) {\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n uint256 resultUint = Common.sqrt(uint256(xyInt));\n result = wrap(int256(resultUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The SD59x18 number for which to calculate the inverse.\n/// @return result The inverse as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~195_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The SD59x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n default { result := uMAX_SD59x18 }\n }\n\n if (result.unwrap() == uMAX_SD59x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt <= 0) {\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n int256 sign;\n if (xInt >= uUNIT) {\n sign = 1;\n } else {\n sign = -1;\n // Inline the fixed-point inversion to save gas.\n xInt = uUNIT_SQUARED / xInt;\n }\n\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(uint256(xInt / uUNIT));\n\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\n int256 resultInt = int256(n) * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n int256 y = xInt >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultInt * sign);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n int256 DOUBLE_UNIT = 2e18;\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultInt = resultInt + delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n resultInt *= sign;\n result = wrap(resultInt);\n }\n}\n\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\n///\n/// @dev Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv18}.\n/// - None of the inputs can be `MIN_SD59x18`.\n/// - The result must fit in SD59x18.\n///\n/// @param x The multiplicand as an SD59x18 number.\n/// @param y The multiplier as an SD59x18 number.\n/// @return result The product as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\n }\n\n // Get hold of the absolute values of x and y.\n uint256 xAbs;\n uint256 yAbs;\n unchecked {\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\n }\n\n // Compute the absolute value (x*y÷UNIT). The resulting value must fit in SD59x18.\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\n }\n\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\n // negative, 0 for positive or zero).\n bool sameSign = (xInt ^ yInt) > -1;\n\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\n unchecked {\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\n }\n}\n\n/// @notice Raises x to the power of y using the following formula:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y Exponent to raise x to, as an SD59x18 number\n/// @return result x raised to power y, as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n int256 yInt = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xInt == 0) {\n return yInt == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xInt == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yInt == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yInt == uUNIT) {\n return x;\n }\n\n // Calculate the result using the formula.\n result = exp2(mul(log2(x), y));\n}\n\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\n/// - The result must fit in SD59x18.\n///\n/// @param x The base as an SD59x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\n uint256 xAbs = uint256(abs(x).unwrap());\n\n // Calculate the first iteration of the loop in advance.\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n uint256 yAux = y;\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\n xAbs = Common.mulDiv18(xAbs, xAbs);\n\n // Equivalent to `y % 2 == 1`.\n if (yAux & 1 > 0) {\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\n }\n }\n\n // The result must fit in SD59x18.\n if (resultAbs > uint256(uMAX_SD59x18)) {\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\n }\n\n unchecked {\n // Is the base negative and the exponent odd? If yes, the result should be negative.\n int256 resultInt = int256(resultAbs);\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\n if (isNegative) {\n resultInt = -resultInt;\n }\n result = wrap(resultInt);\n }\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - Only the positive root is returned.\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x cannot be negative, since complex numbers are not supported.\n/// - x must be less than `MAX_SD59x18 / UNIT`.\n///\n/// @param x The SD59x18 number for which to calculate the square root.\n/// @return result The result as an SD59x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\n int256 xInt = x.unwrap();\n if (xInt < 0) {\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\n }\n if (xInt > uMAX_SD59x18 / uUNIT) {\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\n }\n\n unchecked {\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\n // In this case, the two numbers are both the square root.\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\n result = wrap(int256(resultUint));\n }\n}\n" - }, - "@prb/math/src/sd59x18/ValueType.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type int256.\ntype SD59x18 is int256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoInt256,\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Math.abs,\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.log10,\n Math.log2,\n Math.ln,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.uncheckedUnary,\n Helpers.xor\n} for SD59x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the SD59x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.or as |,\n Helpers.sub as -,\n Helpers.unary as -,\n Helpers.xor as ^\n} for SD59x18 global;\n" - }, - "@prb/math/src/UD2x18.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗╚════██╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║ █████╔╝ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══╝ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud2x18/Casting.sol\";\nimport \"./ud2x18/Constants.sol\";\nimport \"./ud2x18/Errors.sol\";\nimport \"./ud2x18/ValueType.sol\";\n" - }, - "@prb/math/src/ud2x18/Casting.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { UD60x18 } from \"../ud60x18/ValueType.sol\";\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD2x18 number into SD1x18.\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(uMAX_SD1x18)) {\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(xUint));\n}\n\n/// @notice Casts a UD2x18 number into SD59x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\n}\n\n/// @notice Casts a UD2x18 number into UD60x18.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint128.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\n result = uint128(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint256.\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\n result = uint256(UD2x18.unwrap(x));\n}\n\n/// @notice Casts a UD2x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\n uint64 xUint = UD2x18.unwrap(x);\n if (xUint > uint64(Common.MAX_UINT40)) {\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n\n/// @notice Unwrap a UD2x18 number into uint64.\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\n result = UD2x18.unwrap(x);\n}\n\n/// @notice Wraps a uint64 number into UD2x18.\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\n result = UD2x18.wrap(x);\n}\n" - }, - "@prb/math/src/ud2x18/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @dev Euler's number as a UD2x18 number.\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\n\n/// @dev The maximum value a UD2x18 number can have.\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\n\n/// @dev PI as a UD2x18 number.\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD2x18.\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\nuint64 constant uUNIT = 1e18;\n" - }, - "@prb/math/src/ud2x18/Errors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD2x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\n\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\n" - }, - "@prb/math/src/ud2x18/ValueType.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\n\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\n/// storage.\ntype UD2x18 is uint64;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoSD59x18,\n Casting.intoUD60x18,\n Casting.intoUint256,\n Casting.intoUint128,\n Casting.intoUint40,\n Casting.unwrap\n} for UD2x18 global;\n" - }, - "@prb/math/src/UD60x18.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\n/*\n\n██████╗ ██████╗ ██████╗ ███╗ ███╗ █████╗ ████████╗██╗ ██╗\n██╔══██╗██╔══██╗██╔══██╗████╗ ████║██╔══██╗╚══██╔══╝██║ ██║\n██████╔╝██████╔╝██████╔╝██╔████╔██║███████║ ██║ ███████║\n██╔═══╝ ██╔══██╗██╔══██╗██║╚██╔╝██║██╔══██║ ██║ ██╔══██║\n██║ ██║ ██║██████╔╝██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║\n╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝\n\n██╗ ██╗██████╗ ██████╗ ██████╗ ██╗ ██╗ ██╗ █████╗\n██║ ██║██╔══██╗██╔════╝ ██╔═████╗╚██╗██╔╝███║██╔══██╗\n██║ ██║██║ ██║███████╗ ██║██╔██║ ╚███╔╝ ╚██║╚█████╔╝\n██║ ██║██║ ██║██╔═══██╗████╔╝██║ ██╔██╗ ██║██╔══██╗\n╚██████╔╝██████╔╝╚██████╔╝╚██████╔╝██╔╝ ██╗ ██║╚█████╔╝\n ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚════╝\n\n*/\n\nimport \"./ud60x18/Casting.sol\";\nimport \"./ud60x18/Constants.sol\";\nimport \"./ud60x18/Conversions.sol\";\nimport \"./ud60x18/Errors.sol\";\nimport \"./ud60x18/Helpers.sol\";\nimport \"./ud60x18/Math.sol\";\nimport \"./ud60x18/ValueType.sol\";\n" - }, - "@prb/math/src/ud60x18/Casting.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Errors.sol\" as CastingErrors;\nimport { MAX_UINT128, MAX_UINT40 } from \"../Common.sol\";\nimport { uMAX_SD1x18 } from \"../sd1x18/Constants.sol\";\nimport { SD1x18 } from \"../sd1x18/ValueType.sol\";\nimport { uMAX_SD59x18 } from \"../sd59x18/Constants.sol\";\nimport { SD59x18 } from \"../sd59x18/ValueType.sol\";\nimport { uMAX_UD2x18 } from \"../ud2x18/Constants.sol\";\nimport { UD2x18 } from \"../ud2x18/ValueType.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Casts a UD60x18 number into SD1x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD1x18`.\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(int256(uMAX_SD1x18))) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\n }\n result = SD1x18.wrap(int64(uint64(xUint)));\n}\n\n/// @notice Casts a UD60x18 number into UD2x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_UD2x18`.\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uMAX_UD2x18) {\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\n }\n result = UD2x18.wrap(uint64(xUint));\n}\n\n/// @notice Casts a UD60x18 number into SD59x18.\n/// @dev Requirements:\n/// - x must be less than or equal to `uMAX_SD59x18`.\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > uint256(uMAX_SD59x18)) {\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\n }\n result = SD59x18.wrap(int256(xUint));\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev This is basically an alias for {unwrap}.\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Casts a UD60x18 number into uint128.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT128`.\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT128) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\n }\n result = uint128(xUint);\n}\n\n/// @notice Casts a UD60x18 number into uint40.\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UINT40`.\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\n uint256 xUint = UD60x18.unwrap(x);\n if (xUint > MAX_UINT40) {\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\n }\n result = uint40(xUint);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Alias for {wrap}.\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n\n/// @notice Unwraps a UD60x18 number into uint256.\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x);\n}\n\n/// @notice Wraps a uint256 number into the UD60x18 value type.\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\n result = UD60x18.wrap(x);\n}\n" - }, - "@prb/math/src/ud60x18/Constants.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n// NOTICE: the \"u\" prefix stands for \"unwrapped\".\n\n/// @dev Euler's number as a UD60x18 number.\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\n\n/// @dev The maximum input permitted in {exp}.\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\n\n/// @dev The maximum input permitted in {exp2}.\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\n\n/// @dev Half the UNIT number.\nuint256 constant uHALF_UNIT = 0.5e18;\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\n\n/// @dev $log_2(10)$ as a UD60x18 number.\nuint256 constant uLOG2_10 = 3_321928094887362347;\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\n\n/// @dev $log_2(e)$ as a UD60x18 number.\nuint256 constant uLOG2_E = 1_442695040888963407;\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\n\n/// @dev The maximum value a UD60x18 number can have.\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\n\n/// @dev The maximum whole value a UD60x18 number can have.\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\n\n/// @dev PI as a UD60x18 number.\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\n\n/// @dev The unit number, which gives the decimal precision of UD60x18.\nuint256 constant uUNIT = 1e18;\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\n\n/// @dev The unit number squared.\nuint256 constant uUNIT_SQUARED = 1e36;\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\n\n/// @dev Zero as a UD60x18 number.\nUD60x18 constant ZERO = UD60x18.wrap(0);\n" - }, - "@prb/math/src/ud60x18/Conversions.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { uMAX_UD60x18, uUNIT } from \"./Constants.sol\";\nimport { PRBMath_UD60x18_Convert_Overflow } from \"./Errors.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\n/// @dev The result is rounded toward zero.\n/// @param x The UD60x18 number to convert.\n/// @return result The same number in basic integer form.\nfunction convert(UD60x18 x) pure returns (uint256 result) {\n result = UD60x18.unwrap(x) / uUNIT;\n}\n\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\n///\n/// @dev Requirements:\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\n///\n/// @param x The basic integer to convert.\n/// @param result The same number converted to UD60x18.\nfunction convert(uint256 x) pure returns (UD60x18 result) {\n if (x > uMAX_UD60x18 / uUNIT) {\n revert PRBMath_UD60x18_Convert_Overflow(x);\n }\n unchecked {\n result = UD60x18.wrap(x * uUNIT);\n }\n}\n" - }, - "@prb/math/src/ud60x18/Errors.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Thrown when ceiling a number overflows UD60x18.\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\n\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\n\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\n\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\n\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\n\n/// @notice Thrown when taking the logarithm of a number less than 1.\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\n\n/// @notice Thrown when calculating the square root overflows UD60x18.\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\n" - }, - "@prb/math/src/ud60x18/Helpers.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport { wrap } from \"./Casting.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() + y.unwrap());\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & bits);\n}\n\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() & y.unwrap());\n}\n\n/// @notice Implements the equal operation (==) in the UD60x18 type.\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() == y.unwrap();\n}\n\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() > y.unwrap();\n}\n\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() >= y.unwrap();\n}\n\n/// @notice Implements a zero comparison check function in the UD60x18 type.\nfunction isZero(UD60x18 x) pure returns (bool result) {\n // This wouldn't work if x could be negative.\n result = x.unwrap() == 0;\n}\n\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() << bits);\n}\n\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() < y.unwrap();\n}\n\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() <= y.unwrap();\n}\n\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() % y.unwrap());\n}\n\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\n result = x.unwrap() != y.unwrap();\n}\n\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\n result = wrap(~x.unwrap());\n}\n\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() | y.unwrap());\n}\n\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() >> bits);\n}\n\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() - y.unwrap());\n}\n\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() + y.unwrap());\n }\n}\n\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(x.unwrap() - y.unwrap());\n }\n}\n\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(x.unwrap() ^ y.unwrap());\n}\n" - }, - "@prb/math/src/ud60x18/Math.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"../Common.sol\" as Common;\nimport \"./Errors.sol\" as Errors;\nimport { wrap } from \"./Casting.sol\";\nimport {\n uEXP_MAX_INPUT,\n uEXP2_MAX_INPUT,\n uHALF_UNIT,\n uLOG2_10,\n uLOG2_E,\n uMAX_UD60x18,\n uMAX_WHOLE_UD60x18,\n UNIT,\n uUNIT,\n uUNIT_SQUARED,\n ZERO\n} from \"./Constants.sol\";\nimport { UD60x18 } from \"./ValueType.sol\";\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n/// @notice Calculates the arithmetic average of x and y using the following formula:\n///\n/// $$\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\n/// $$\n///\n/// In English, this is what this formula does:\n///\n/// 1. AND x and y.\n/// 2. Calculate half of XOR x and y.\n/// 3. Add the two results together.\n///\n/// This technique is known as SWAR, which stands for \"SIMD within a register\". You can read more about it here:\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The arithmetic average as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n unchecked {\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\n }\n}\n\n/// @notice Yields the smallest whole number greater than or equal to x.\n///\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n///\n/// Requirements:\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\n///\n/// @param x The UD60x18 number to ceil.\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint > uMAX_WHOLE_UD60x18) {\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\n }\n\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `UNIT - remainder`.\n let delta := sub(uUNIT, remainder)\n\n // Equivalent to `x + remainder > 0 ? delta : 0`.\n result := add(x, mul(delta, gt(remainder, 0)))\n }\n}\n\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @param x The numerator as a UD60x18 number.\n/// @param y The denominator as a UD60x18 number.\n/// @param result The quotient as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\n}\n\n/// @notice Calculates the natural exponent of x using the following formula:\n///\n/// $$\n/// e^x = 2^{x * log_2{e}}\n/// $$\n///\n/// @dev Requirements:\n/// - x must be less than 133_084258667509499441.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // This check prevents values greater than 192e18 from being passed to {exp2}.\n if (xUint > uEXP_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\n }\n\n unchecked {\n // Inline the fixed-point multiplication to save gas.\n uint256 doubleUnitProduct = xUint * uLOG2_E;\n result = exp2(wrap(doubleUnitProduct / uUNIT));\n }\n}\n\n/// @notice Calculates the binary exponent of x using the binary fraction method.\n///\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\n///\n/// Requirements:\n/// - x must be less than 192e18.\n/// - The result must fit in UD60x18.\n///\n/// @param x The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\n if (xUint > uEXP2_MAX_INPUT) {\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\n }\n\n // Convert x to the 192.64-bit fixed-point format.\n uint256 x_192x64 = (xUint << 64) / uUNIT;\n\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\n result = wrap(Common.exp2(x_192x64));\n}\n\n/// @notice Yields the greatest whole number less than or equal to x.\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\n/// @param x The UD60x18 number to floor.\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n // Equivalent to `x % UNIT`.\n let remainder := mod(x, uUNIT)\n\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\n result := sub(x, mul(remainder, gt(remainder, 0)))\n }\n}\n\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\n/// @param x The UD60x18 number to get the fractional part of.\n/// @param result The fractional part of x as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\n assembly (\"memory-safe\") {\n result := mod(x, uUNIT)\n }\n}\n\n/// @notice Calculates the geometric mean of x and y, i.e. $\\sqrt{x * y}$, rounding down.\n///\n/// @dev Requirements:\n/// - x * y must fit in UD60x18.\n///\n/// @param x The first operand as a UD60x18 number.\n/// @param y The second operand as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n if (xUint == 0 || yUint == 0) {\n return ZERO;\n }\n\n unchecked {\n // Checking for overflow this way is faster than letting Solidity do it.\n uint256 xyUint = xUint * yUint;\n if (xyUint / xUint != yUint) {\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\n }\n\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\n // during multiplication. See the comments in {Common.sqrt}.\n result = wrap(Common.sqrt(xyUint));\n }\n}\n\n/// @notice Calculates the inverse of x.\n///\n/// @dev Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must not be zero.\n///\n/// @param x The UD60x18 number for which to calculate the inverse.\n/// @return result The inverse as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n result = wrap(uUNIT_SQUARED / x.unwrap());\n }\n}\n\n/// @notice Calculates the natural logarithm of x using the following formula:\n///\n/// $$\n/// ln{x} = log_2{x} / log_2{e}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\n/// @return result The natural logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\n unchecked {\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\n // {log2} can return is ~196_205294292027477728.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\n }\n}\n\n/// @notice Calculates the common logarithm of x using the following formula:\n///\n/// $$\n/// log_{10}{x} = log_2{x} / log_2{10}\n/// $$\n///\n/// However, if x is an exact power of ten, a hard coded value is returned.\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2}.\n///\n/// Requirements:\n/// - Refer to the requirements in {log2}.\n///\n/// @param x The UD60x18 number for which to calculate the common logarithm.\n/// @return result The common logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\n // prettier-ignore\n assembly (\"memory-safe\") {\n switch x\n case 1 { result := mul(uUNIT, sub(0, 18)) }\n case 10 { result := mul(uUNIT, sub(1, 18)) }\n case 100 { result := mul(uUNIT, sub(2, 18)) }\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\n case 1000000000000000000 { result := 0 }\n case 10000000000000000000 { result := uUNIT }\n case 100000000000000000000 { result := mul(uUNIT, 2) }\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\n default { result := uMAX_UD60x18 }\n }\n\n if (result.unwrap() == uMAX_UD60x18) {\n unchecked {\n // Inline the fixed-point division to save gas.\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\n }\n }\n}\n\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\n///\n/// $$\n/// log_2{x} = n + log_2{y}, \\text{ where } y = x*2^{-n}, \\ y \\in [1, 2)\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, the input is inverted:\n///\n/// $$\n/// log_2{x} = -log_2{\\frac{1}{x}}\n/// $$\n///\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\n///\n/// Notes:\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\n///\n/// Requirements:\n/// - x must be greater than zero.\n///\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\n/// @return result The binary logarithm as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n if (xUint < uUNIT) {\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\n }\n\n unchecked {\n // Calculate the integer part of the logarithm.\n uint256 n = Common.msb(xUint / uUNIT);\n\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\n // n is at most 255 and UNIT is 1e18.\n uint256 resultUint = n * uUNIT;\n\n // Calculate $y = x * 2^{-n}$.\n uint256 y = xUint >> n;\n\n // If y is the unit number, the fractional part is zero.\n if (y == uUNIT) {\n return wrap(resultUint);\n }\n\n // Calculate the fractional part via the iterative approximation.\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\n uint256 DOUBLE_UNIT = 2e18;\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\n y = (y * y) / uUNIT;\n\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\n if (y >= DOUBLE_UNIT) {\n // Add the 2^{-m} factor to the logarithm.\n resultUint += delta;\n\n // Halve y, which corresponds to z/2 in the Wikipedia article.\n y >>= 1;\n }\n }\n result = wrap(resultUint);\n }\n}\n\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\n///\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv}.\n///\n/// Requirements:\n/// - Refer to the requirements in {Common.mulDiv}.\n///\n/// @dev See the documentation in {Common.mulDiv18}.\n/// @param x The multiplicand as a UD60x18 number.\n/// @param y The multiplier as a UD60x18 number.\n/// @return result The product as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\n}\n\n/// @notice Raises x to the power of y.\n///\n/// For $1 \\leq x \\leq \\infty$, the following standard formula is used:\n///\n/// $$\n/// x^y = 2^{log_2{x} * y}\n/// $$\n///\n/// For $0 \\leq x \\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\n///\n/// $$\n/// i = \\frac{1}{x}\n/// w = 2^{log_2{i} * y}\n/// x^y = \\frac{1}{w}\n/// $$\n///\n/// @dev Notes:\n/// - Refer to the notes in {log2} and {mul}.\n/// - Returns `UNIT` for 0^0.\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\n///\n/// Requirements:\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a UD60x18 number.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n uint256 yUint = y.unwrap();\n\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\n if (xUint == 0) {\n return yUint == 0 ? UNIT : ZERO;\n }\n // If x is `UNIT`, the result is always `UNIT`.\n else if (xUint == uUNIT) {\n return UNIT;\n }\n\n // If y is zero, the result is always `UNIT`.\n if (yUint == 0) {\n return UNIT;\n }\n // If y is `UNIT`, the result is always x.\n else if (yUint == uUNIT) {\n return x;\n }\n\n // If x is greater than `UNIT`, use the standard formula.\n if (xUint > uUNIT) {\n result = exp2(mul(log2(x), y));\n }\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\n else {\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\n UD60x18 w = exp2(mul(log2(i), y));\n result = wrap(uUNIT_SQUARED / w.unwrap());\n }\n}\n\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\n/// algorithm \"exponentiation by squaring\".\n///\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\n///\n/// Notes:\n/// - Refer to the notes in {Common.mulDiv18}.\n/// - Returns `UNIT` for 0^0.\n///\n/// Requirements:\n/// - The result must fit in UD60x18.\n///\n/// @param x The base as a UD60x18 number.\n/// @param y The exponent as a uint256.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\n // Calculate the first iteration of the loop in advance.\n uint256 xUint = x.unwrap();\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\n\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\n for (y >>= 1; y > 0; y >>= 1) {\n xUint = Common.mulDiv18(xUint, xUint);\n\n // Equivalent to `y % 2 == 1`.\n if (y & 1 > 0) {\n resultUint = Common.mulDiv18(resultUint, xUint);\n }\n }\n result = wrap(resultUint);\n}\n\n/// @notice Calculates the square root of x using the Babylonian method.\n///\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\n///\n/// Notes:\n/// - The result is rounded toward zero.\n///\n/// Requirements:\n/// - x must be less than `MAX_UD60x18 / UNIT`.\n///\n/// @param x The UD60x18 number for which to calculate the square root.\n/// @return result The result as a UD60x18 number.\n/// @custom:smtchecker abstract-function-nondet\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\n uint256 xUint = x.unwrap();\n\n unchecked {\n if (xUint > uMAX_UD60x18 / uUNIT) {\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\n }\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\n // In this case, the two numbers are both the square root.\n result = wrap(Common.sqrt(xUint * uUNIT));\n }\n}\n" - }, - "@prb/math/src/ud60x18/ValueType.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.19;\n\nimport \"./Casting.sol\" as Casting;\nimport \"./Helpers.sol\" as Helpers;\nimport \"./Math.sol\" as Math;\n\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\n/// @dev The value type is defined here so it can be imported in all other files.\ntype UD60x18 is uint256;\n\n/*//////////////////////////////////////////////////////////////////////////\n CASTING\n//////////////////////////////////////////////////////////////////////////*/\n\nusing {\n Casting.intoSD1x18,\n Casting.intoUD2x18,\n Casting.intoSD59x18,\n Casting.intoUint128,\n Casting.intoUint256,\n Casting.intoUint40,\n Casting.unwrap\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n MATHEMATICAL FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Math.avg,\n Math.ceil,\n Math.div,\n Math.exp,\n Math.exp2,\n Math.floor,\n Math.frac,\n Math.gm,\n Math.inv,\n Math.ln,\n Math.log10,\n Math.log2,\n Math.mul,\n Math.pow,\n Math.powu,\n Math.sqrt\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n HELPER FUNCTIONS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes the functions in this library callable on the UD60x18 type.\nusing {\n Helpers.add,\n Helpers.and,\n Helpers.eq,\n Helpers.gt,\n Helpers.gte,\n Helpers.isZero,\n Helpers.lshift,\n Helpers.lt,\n Helpers.lte,\n Helpers.mod,\n Helpers.neq,\n Helpers.not,\n Helpers.or,\n Helpers.rshift,\n Helpers.sub,\n Helpers.uncheckedAdd,\n Helpers.uncheckedSub,\n Helpers.xor\n} for UD60x18 global;\n\n/*//////////////////////////////////////////////////////////////////////////\n OPERATORS\n//////////////////////////////////////////////////////////////////////////*/\n\n// The global \"using for\" directive makes it possible to use these operators on the UD60x18 type.\nusing {\n Helpers.add as +,\n Helpers.and2 as &,\n Math.div as /,\n Helpers.eq as ==,\n Helpers.gt as >,\n Helpers.gte as >=,\n Helpers.lt as <,\n Helpers.lte as <=,\n Helpers.or as |,\n Helpers.mod as %,\n Math.mul as *,\n Helpers.neq as !=,\n Helpers.not as ~,\n Helpers.sub as -,\n Helpers.xor as ^\n} for UD60x18 global;\n" - }, - "contracts/DecentAutonomousAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {IHatsElectionsEligibility} from \"./interfaces/hats/modules/IHatsElectionsEligibility.sol\";\nimport {FactoryFriendly} from \"@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol\";\nimport {ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {IDecentAutonomousAdmin} from \"./interfaces/IDecentAutonomousAdmin.sol\";\n\ncontract DecentAutonomousAdmin is\n IDecentAutonomousAdmin,\n ERC165,\n FactoryFriendly\n{\n // //////////////////////////////////////////////////////////////\n // initializer\n // //////////////////////////////////////////////////////////////\n function setUp(bytes memory initializeParams) public override initializer {}\n\n // //////////////////////////////////////////////////////////////\n // Public Functions\n // //////////////////////////////////////////////////////////////\n function triggerStartNextTerm(TriggerStartArgs calldata args) public {\n if (\n args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId) ==\n false\n ) revert NotCurrentWearer();\n\n IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility(\n args.hatsProtocol.getHatEligibilityModule(args.hatId)\n );\n\n hatsElectionModule.startNextTerm();\n\n // This will burn the hat since wearer is no longer eligible\n args.hatsProtocol.checkHatWearerStatus(args.hatId, args.currentWearer);\n // This will mint the hat to the nominated wearer\n args.hatsProtocol.mintHat(args.hatId, args.nominatedWearer);\n }\n\n function supportsInterface(\n bytes4 interfaceId\n ) public view override returns (bool) {\n return\n interfaceId == type(IDecentAutonomousAdmin).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n}\n" - }, - "contracts/DecentHatsCreationModule.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {LockupLinear, Broker} from \"./interfaces/sablier/types/DataTypes.sol\";\nimport {IHatsModuleFactory} from \"./interfaces/hats/IHatsModuleFactory.sol\";\nimport {IHatsElectionsEligibility} from \"./interfaces/hats/modules/IHatsElectionsEligibility.sol\";\nimport {ModuleProxyFactory} from \"@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {DecentHatsUtils} from \"./DecentHatsUtils.sol\";\n\ncontract DecentHatsCreationModule is DecentHatsUtils {\n struct TopHatParams {\n string details;\n string imageURI;\n }\n\n struct AdminHatParams {\n string details;\n string imageURI;\n bool isMutable;\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n IERC6551Registry erc6551Registry;\n IHatsModuleFactory hatsModuleFactory;\n ModuleProxyFactory moduleProxyFactory;\n address keyValuePairs;\n address decentAutonomousAdminMasterCopy;\n address hatsAccountImplementation;\n address hatsElectionsEligibilityImplementation;\n TopHatParams topHat;\n AdminHatParams adminHat;\n HatParams[] hats;\n }\n\n /* /////////////////////////////////////////////////////////////////////////////\n EXTERNAL FUNCTIONS\n ///////////////////////////////////////////////////////////////////////////// */\n /**\n * @notice For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided, then transfers the top hat\n * to the calling safe.\n *\n * @notice This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev For each hat that is included, if the hat is:\n * - termed, its stream funds on are targeted directly at the nominated wearer. The wearer should directly call `withdraw-`\n * on the Sablier contract.\n * - untermed, its stream funds are targeted at the hat's smart account. In order to withdraw funds from the stream, the\n * hat's smart account must be the one call to `withdraw-` on the Sablier contract, setting the recipient arg to its wearer.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) external {\n IHats hatsProtocol = params.hatsProtocol;\n address hatsAccountImplementation = params.hatsAccountImplementation;\n IERC6551Registry erc6551Registry = params.erc6551Registry;\n\n // Create Top Hat\n (uint256 topHatId, address topHatAccount) = _processTopHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n params.keyValuePairs,\n params.topHat\n );\n\n // Create Admin Hat\n uint256 adminHatId = _processAdminHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n topHatId,\n topHatAccount,\n params.moduleProxyFactory,\n params.decentAutonomousAdminMasterCopy,\n params.adminHat\n );\n\n // Create Role Hats\n for (uint256 i = 0; i < params.hats.length; ) {\n HatParams memory hat = params.hats[i];\n _processHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n topHatId,\n topHatAccount,\n params.hatsModuleFactory,\n params.hatsElectionsEligibilityImplementation,\n adminHatId,\n hat\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /* /////////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n ///////////////////////////////////////////////////////////////////////////// */\n\n function _processTopHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n address keyValuePairs,\n TopHatParams memory topHat\n ) internal returns (uint256 topHatId, address topHatAccount) {\n // Call lastTopHatId() and properly decode the response\n (bool success, bytes memory data) = address(hatsProtocol).call(\n abi.encodeWithSignature(\"lastTopHatId()\")\n );\n require(success, \"Failed to get lastTopHatId\");\n topHatId = (abi.decode(data, (uint256)) + 1) << 224;\n\n IAvatar(msg.sender).execTransactionFromModule(\n // Mint top hat to the safe\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"mintTopHat(address,string,string)\",\n msg.sender,\n topHat.details,\n topHat.imageURI\n ),\n Enum.Operation.Call\n );\n\n // Create top hat account\n topHatAccount = erc6551Registry.createAccount(\n hatsAccountImplementation,\n SALT,\n block.chainid,\n address(hatsProtocol),\n topHatId\n );\n\n // Declare Top Hat ID to Safe via KeyValuePairs\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n IAvatar(msg.sender).execTransactionFromModule(\n keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function _processAdminHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n uint256 topHatId,\n address topHatAccount,\n ModuleProxyFactory moduleProxyFactory,\n address decentAutonomousAdminMasterCopy,\n AdminHatParams memory adminHat\n ) internal returns (uint256 adminHatId) {\n // Create Admin Hat\n adminHatId = hatsProtocol.getNextId(topHatId);\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"createHat(uint256,string,uint32,address,address,bool,string)\",\n topHatId,\n adminHat.details,\n 1, // only one Admin Hat\n topHatAccount,\n topHatAccount,\n adminHat.isMutable,\n adminHat.imageURI\n ),\n Enum.Operation.Call\n );\n\n // Create Admin Hat's ERC6551 Account\n erc6551Registry.createAccount(\n hatsAccountImplementation,\n SALT,\n block.chainid,\n address(hatsProtocol),\n adminHatId\n );\n\n // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat\n address autonomousAdminModule = moduleProxyFactory.deployModule(\n decentAutonomousAdminMasterCopy,\n abi.encodeWithSignature(\"setUp(bytes)\", bytes(\"\")),\n uint256(\n keccak256(\n abi.encodePacked(\n // for the salt, we'll concatenate our static salt with the id of the Admin Hat\n SALT,\n adminHatId\n )\n )\n )\n );\n\n // Mint Hat to the Decent Autonomous Admin Module\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"mintHat(uint256,address)\",\n adminHatId,\n autonomousAdminModule\n ),\n Enum.Operation.Call\n );\n }\n}\n" - }, - "contracts/DecentHatsUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {LockupLinear, Broker} from \"./interfaces/sablier/types/DataTypes.sol\";\nimport {IHatsModuleFactory} from \"./interfaces/hats/IHatsModuleFactory.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\n\nabstract contract DecentHatsUtils {\n bytes32 public constant SALT =\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n address asset;\n LockupLinear.Timestamps timestamps;\n Broker broker;\n uint128 totalAmount;\n bool cancelable;\n bool transferable;\n }\n\n struct HatParams {\n address wearer;\n string details;\n string imageURI;\n SablierStreamParams[] sablierStreamsParams;\n uint128 termEndDateTs; // If 0, this is an untermed Hat\n uint32 maxSupply;\n bool isMutable;\n }\n\n function _processHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n uint256 topHatId,\n address topHatAccount,\n IHatsModuleFactory hatsModuleFactory,\n address hatsElectionsEligibilityImplementation,\n uint256 adminHatId,\n HatParams memory hat\n ) internal {\n // Create eligibility module if needed\n address eligibilityAddress = _createEligibilityModule(\n hatsProtocol,\n hatsModuleFactory,\n hatsElectionsEligibilityImplementation,\n topHatId,\n topHatAccount,\n adminHatId,\n hat.termEndDateTs\n );\n\n // Create and Mint the Role Hat\n uint256 hatId = _createAndMintHat(\n hatsProtocol,\n adminHatId,\n hat,\n eligibilityAddress,\n topHatAccount\n );\n\n // Get the stream recipient (based on termed or not)\n address streamRecipient = _setupStreamRecipient(\n erc6551Registry,\n hatsAccountImplementation,\n address(hatsProtocol),\n hat.termEndDateTs,\n hat.wearer,\n hatId\n );\n\n // Create streams\n _processSablierStreams(hat.sablierStreamsParams, streamRecipient);\n }\n\n function _createEligibilityModule(\n IHats hatsProtocol,\n IHatsModuleFactory hatsModuleFactory,\n address hatsElectionsEligibilityImplementation,\n uint256 topHatId,\n address topHatAccount,\n uint256 adminHatId,\n uint128 termEndDateTs\n ) private returns (address) {\n if (termEndDateTs != 0) {\n return\n hatsModuleFactory.createHatsModule(\n hatsElectionsEligibilityImplementation,\n hatsProtocol.getNextId(adminHatId),\n abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID]\n abi.encode(termEndDateTs),\n uint256(SALT)\n );\n }\n return topHatAccount;\n }\n\n function _createAndMintHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n HatParams memory hat,\n address eligibilityAddress,\n address topHatAccount\n ) private returns (uint256) {\n uint256 hatId = hatsProtocol.getNextId(adminHatId);\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"createHat(uint256,string,uint32,address,address,bool,string)\",\n adminHatId,\n hat.details,\n hat.maxSupply,\n eligibilityAddress,\n topHatAccount,\n hat.isMutable,\n hat.imageURI\n ),\n Enum.Operation.Call\n );\n\n // If the hat is termed, nominate the wearer as the eligible member\n if (hat.termEndDateTs != 0) {\n address[] memory nominatedWearers = new address[](1);\n nominatedWearers[0] = hat.wearer;\n\n IAvatar(msg.sender).execTransactionFromModule(\n eligibilityAddress,\n 0,\n abi.encodeWithSignature(\n \"elect(uint128,address[])\",\n hat.termEndDateTs,\n nominatedWearers\n ),\n Enum.Operation.Call\n );\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(hatsProtocol),\n 0,\n abi.encodeWithSignature(\n \"mintHat(uint256,address)\",\n hatId,\n hat.wearer\n ),\n Enum.Operation.Call\n );\n return hatId;\n }\n\n // Exists to avoid stack too deep errors\n function _setupStreamRecipient(\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n address hatsProtocol,\n uint128 termEndDateTs,\n address wearer,\n uint256 hatId\n ) private returns (address) {\n // If the hat is termed, the wearer is the stream recipient\n if (termEndDateTs != 0) {\n return wearer;\n }\n\n // Otherwise, the Hat's smart account is the stream recipient\n return\n erc6551Registry.createAccount(\n hatsAccountImplementation,\n SALT,\n block.chainid,\n hatsProtocol,\n hatId\n );\n }\n\n function _processSablierStreams(\n SablierStreamParams[] memory streamParams,\n address streamRecipient\n ) private {\n for (uint256 i = 0; i < streamParams.length; ) {\n SablierStreamParams memory sablierStreamParams = streamParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierStreamParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n sablierStreamParams.sablier,\n sablierStreamParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierStreamParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n LockupLinear.CreateWithTimestamps({\n sender: sablierStreamParams.sender,\n recipient: streamRecipient,\n totalAmount: sablierStreamParams.totalAmount,\n asset: IERC20(sablierStreamParams.asset),\n cancelable: sablierStreamParams.cancelable,\n transferable: sablierStreamParams.transferable,\n timestamps: sablierStreamParams.timestamps,\n broker: sablierStreamParams.broker\n })\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n}\n" - }, - "contracts/DecentSablierStreamManagement.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {ISablierV2Lockup} from \"./interfaces/sablier/ISablierV2Lockup.sol\";\nimport {Lockup} from \"./interfaces/sablier/types/DataTypes.sol\";\n\ncontract DecentSablierStreamManagement {\n string public constant NAME = \"DecentSablierStreamManagement\";\n\n function withdrawMaxFromStream(\n ISablierV2Lockup sablier,\n address recipientHatAccount,\n uint256 streamId,\n address to\n ) public {\n // Check if there are funds to withdraw\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return;\n }\n\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\n IAvatar(msg.sender).execTransactionFromModule(\n recipientHatAccount,\n 0,\n abi.encodeWithSignature(\n \"execute(address,uint256,bytes,uint8)\",\n address(sablier),\n 0,\n abi.encodeWithSignature(\n \"withdrawMax(uint256,address)\",\n streamId,\n to\n ),\n 0\n ),\n Enum.Operation.Call\n );\n }\n\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\n // Check if the stream can be cancelled\n Lockup.Status streamStatus = sablier.statusOf(streamId);\n if (\n streamStatus != Lockup.Status.PENDING &&\n streamStatus != Lockup.Status.STREAMING\n ) {\n return;\n }\n\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablier),\n 0,\n abi.encodeWithSignature(\"cancel(uint256)\", streamId),\n Enum.Operation.Call\n );\n }\n}\n" - }, - "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/GnosisSafeL2.sol';\n" - }, - "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/libraries/MultiSendCallOnly.sol';\n" - }, - "contracts/hardhat-dependency-compiler/@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol';\n" - }, - "contracts/hardhat-dependency-compiler/@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol": { - "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@gnosis.pm/zodiac/contracts/factory/ModuleProxyFactory.sol';\n" - }, - "contracts/interfaces/hats/HatsErrors.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface HatsErrors {\n /// @notice Emitted when `user` is attempting to perform an action on `hatId` but is not wearing one of `hatId`'s admin hats\n /// @dev Can be equivalent to `NotHatWearer(buildHatId(hatId))`, such as when emitted by `approveLinkTopHatToTree` or `relinkTopHatToTree`\n error NotAdmin(address user, uint256 hatId);\n\n /// @notice Emitted when attempting to perform an action as or for an account that is not a wearer of a given hat\n error NotHatWearer();\n\n /// @notice Emitted when attempting to perform an action that requires being either an admin or wearer of a given hat\n error NotAdminOrWearer();\n\n /// @notice Emitted when attempting to mint `hatId` but `hatId`'s maxSupply has been reached\n error AllHatsWorn(uint256 hatId);\n\n /// @notice Emitted when attempting to create a hat with a level 14 hat as its admin\n error MaxLevelsReached();\n\n /// @notice Emitted when an attempted hat id has empty intermediate level(s)\n error InvalidHatId();\n\n /// @notice Emitted when attempting to mint `hatId` to a `wearer` who is already wearing the hat\n error AlreadyWearingHat(address wearer, uint256 hatId);\n\n /// @notice Emitted when attempting to mint a non-existant hat\n error HatDoesNotExist(uint256 hatId);\n\n /// @notice Emmitted when attempting to mint or transfer a hat that is not active\n error HatNotActive();\n\n /// @notice Emitted when attempting to mint or transfer a hat to an ineligible wearer\n error NotEligible();\n\n /// @notice Emitted when attempting to check or set a hat's status from an account that is not that hat's toggle module\n error NotHatsToggle();\n\n /// @notice Emitted when attempting to check or set a hat wearer's status from an account that is not that hat's eligibility module\n error NotHatsEligibility();\n\n /// @notice Emitted when array arguments to a batch function have mismatching lengths\n error BatchArrayLengthMismatch();\n\n /// @notice Emitted when attempting to mutate or transfer an immutable hat\n error Immutable();\n\n /// @notice Emitted when attempting to change a hat's maxSupply to a value lower than its current supply\n error NewMaxSupplyTooLow();\n\n /// @notice Emitted when attempting to link a tophat to a new admin for which the tophat serves as an admin\n error CircularLinkage();\n\n /// @notice Emitted when attempting to link or relink a tophat to a separate tree\n error CrossTreeLinkage();\n\n /// @notice Emitted when attempting to link a tophat without a request\n error LinkageNotRequested();\n\n /// @notice Emitted when attempting to unlink a tophat that does not have a wearer\n /// @dev This ensures that unlinking never results in a bricked tophat\n error InvalidUnlink();\n\n /// @notice Emmited when attempting to change a hat's eligibility or toggle module to the zero address\n error ZeroAddress();\n\n /// @notice Emmitted when attempting to change a hat's details or imageURI to a string with over 7000 bytes (~characters)\n /// @dev This protects against a DOS attack where an admin iteratively extend's a hat's details or imageURI\n /// to be so long that reading it exceeds the block gas limit, breaking `uri()` and `viewHat()`\n error StringTooLong();\n}\n" - }, - "contracts/interfaces/hats/HatsEvents.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface HatsEvents {\n /// @notice Emitted when a new hat is created\n /// @param id The id for the new hat\n /// @param details A description of the Hat\n /// @param maxSupply The total instances of the Hat that can be worn at once\n /// @param eligibility The address that can report on the Hat wearer's status\n /// @param toggle The address that can deactivate the Hat\n /// @param mutable_ Whether the hat's properties are changeable after creation\n /// @param imageURI The image uri for this hat and the fallback for its\n event HatCreated(\n uint256 id,\n string details,\n uint32 maxSupply,\n address eligibility,\n address toggle,\n bool mutable_,\n string imageURI\n );\n\n /// @notice Emitted when a hat wearer's standing is updated\n /// @dev Eligibility is excluded since the source of truth for eligibility is the eligibility module and may change without a transaction\n /// @param hatId The id of the wearer's hat\n /// @param wearer The wearer's address\n /// @param wearerStanding Whether the wearer is in good standing for the hat\n event WearerStandingChanged(\n uint256 hatId,\n address wearer,\n bool wearerStanding\n );\n\n /// @notice Emitted when a hat's status is updated\n /// @param hatId The id of the hat\n /// @param newStatus Whether the hat is active\n event HatStatusChanged(uint256 hatId, bool newStatus);\n\n /// @notice Emitted when a hat's details are updated\n /// @param hatId The id of the hat\n /// @param newDetails The updated details\n event HatDetailsChanged(uint256 hatId, string newDetails);\n\n /// @notice Emitted when a hat's eligibility module is updated\n /// @param hatId The id of the hat\n /// @param newEligibility The updated eligibiliy module\n event HatEligibilityChanged(uint256 hatId, address newEligibility);\n\n /// @notice Emitted when a hat's toggle module is updated\n /// @param hatId The id of the hat\n /// @param newToggle The updated toggle module\n event HatToggleChanged(uint256 hatId, address newToggle);\n\n /// @notice Emitted when a hat's mutability is updated\n /// @param hatId The id of the hat\n event HatMutabilityChanged(uint256 hatId);\n\n /// @notice Emitted when a hat's maximum supply is updated\n /// @param hatId The id of the hat\n /// @param newMaxSupply The updated max supply\n event HatMaxSupplyChanged(uint256 hatId, uint32 newMaxSupply);\n\n /// @notice Emitted when a hat's image URI is updated\n /// @param hatId The id of the hat\n /// @param newImageURI The updated image URI\n event HatImageURIChanged(uint256 hatId, string newImageURI);\n\n /// @notice Emitted when a tophat linkage is requested by its admin\n /// @param domain The domain of the tree tophat to link\n /// @param newAdmin The tophat's would-be admin in the parent tree\n event TopHatLinkRequested(uint32 domain, uint256 newAdmin);\n\n /// @notice Emitted when a tophat is linked to a another tree\n /// @param domain The domain of the newly-linked tophat\n /// @param newAdmin The tophat's new admin in the parent tree\n event TopHatLinked(uint32 domain, uint256 newAdmin);\n}\n" - }, - "contracts/interfaces/hats/IHats.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\nimport \"./IHatsIdUtilities.sol\";\nimport \"./HatsErrors.sol\";\nimport \"./HatsEvents.sol\";\n\ninterface IHats is IHatsIdUtilities, HatsErrors, HatsEvents {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function batchCreateHats(\n uint256[] calldata _admins,\n string[] calldata _details,\n uint32[] calldata _maxSupplies,\n address[] memory _eligibilityModules,\n address[] memory _toggleModules,\n bool[] calldata _mutables,\n string[] calldata _imageURIs\n ) external returns (bool success);\n\n function getNextId(uint256 _admin) external view returns (uint256 nextId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function batchMintHats(\n uint256[] calldata _hatIds,\n address[] calldata _wearers\n ) external returns (bool success);\n\n function setHatStatus(\n uint256 _hatId,\n bool _newStatus\n ) external returns (bool toggled);\n\n function checkHatStatus(uint256 _hatId) external returns (bool toggled);\n\n function setHatWearerStatus(\n uint256 _hatId,\n address _wearer,\n bool _eligible,\n bool _standing\n ) external returns (bool updated);\n\n function checkHatWearerStatus(\n uint256 _hatId,\n address _wearer\n ) external returns (bool updated);\n\n function renounceHat(uint256 _hatId) external;\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n\n /*//////////////////////////////////////////////////////////////\n HATS ADMIN FUNCTIONS\n //////////////////////////////////////////////////////////////*/\n\n function makeHatImmutable(uint256 _hatId) external;\n\n function changeHatDetails(\n uint256 _hatId,\n string memory _newDetails\n ) external;\n\n function changeHatEligibility(\n uint256 _hatId,\n address _newEligibility\n ) external;\n\n function changeHatToggle(uint256 _hatId, address _newToggle) external;\n\n function changeHatImageURI(\n uint256 _hatId,\n string memory _newImageURI\n ) external;\n\n function changeHatMaxSupply(uint256 _hatId, uint32 _newMaxSupply) external;\n\n function requestLinkTopHatToTree(\n uint32 _topHatId,\n uint256 _newAdminHat\n ) external;\n\n function approveLinkTopHatToTree(\n uint32 _topHatId,\n uint256 _newAdminHat,\n address _eligibility,\n address _toggle,\n string calldata _details,\n string calldata _imageURI\n ) external;\n\n function unlinkTopHatFromTree(uint32 _topHatId, address _wearer) external;\n\n function relinkTopHatWithinTree(\n uint32 _topHatDomain,\n uint256 _newAdminHat,\n address _eligibility,\n address _toggle,\n string calldata _details,\n string calldata _imageURI\n ) external;\n\n /*//////////////////////////////////////////////////////////////\n VIEW FUNCTIONS\n //////////////////////////////////////////////////////////////*/\n\n function viewHat(\n uint256 _hatId\n )\n external\n view\n returns (\n string memory details,\n uint32 maxSupply,\n uint32 supply,\n address eligibility,\n address toggle,\n string memory imageURI,\n uint16 lastHatId,\n bool mutable_,\n bool active\n );\n\n function isWearerOfHat(\n address _user,\n uint256 _hatId\n ) external view returns (bool isWearer);\n\n function isAdminOfHat(\n address _user,\n uint256 _hatId\n ) external view returns (bool isAdmin);\n\n function isInGoodStanding(\n address _wearer,\n uint256 _hatId\n ) external view returns (bool standing);\n\n function isEligible(\n address _wearer,\n uint256 _hatId\n ) external view returns (bool eligible);\n\n function getHatEligibilityModule(\n uint256 _hatId\n ) external view returns (address eligibility);\n\n function getHatToggleModule(\n uint256 _hatId\n ) external view returns (address toggle);\n\n function getHatMaxSupply(\n uint256 _hatId\n ) external view returns (uint32 maxSupply);\n\n function hatSupply(uint256 _hatId) external view returns (uint32 supply);\n\n function getImageURIForHat(\n uint256 _hatId\n ) external view returns (string memory _uri);\n\n function balanceOf(\n address wearer,\n uint256 hatId\n ) external view returns (uint256 balance);\n\n function balanceOfBatch(\n address[] calldata _wearers,\n uint256[] calldata _hatIds\n ) external view returns (uint256[] memory);\n\n function uri(uint256 id) external view returns (string memory _uri);\n}\n" - }, - "contracts/interfaces/hats/IHatsIdUtilities.sol": { - "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHatsIdUtilities {\n function buildHatId(\n uint256 _admin,\n uint16 _newHat\n ) external pure returns (uint256 id);\n\n function getHatLevel(uint256 _hatId) external view returns (uint32 level);\n\n function getLocalHatLevel(\n uint256 _hatId\n ) external pure returns (uint32 level);\n\n function isTopHat(uint256 _hatId) external view returns (bool _topHat);\n\n function isLocalTopHat(\n uint256 _hatId\n ) external pure returns (bool _localTopHat);\n\n function isValidHatId(\n uint256 _hatId\n ) external view returns (bool validHatId);\n\n function getAdminAtLevel(\n uint256 _hatId,\n uint32 _level\n ) external view returns (uint256 admin);\n\n function getAdminAtLocalLevel(\n uint256 _hatId,\n uint32 _level\n ) external pure returns (uint256 admin);\n\n function getTopHatDomain(\n uint256 _hatId\n ) external view returns (uint32 domain);\n\n function getTippyTopHatDomain(\n uint32 _topHatDomain\n ) external view returns (uint32 domain);\n\n function noCircularLinkage(\n uint32 _topHatDomain,\n uint256 _linkedAdmin\n ) external view returns (bool notCircular);\n\n function sameTippyTopHatDomain(\n uint32 _topHatDomain,\n uint256 _newAdminHat\n ) external view returns (bool sameDomain);\n}\n" - }, - "contracts/interfaces/hats/IHatsModuleFactory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\ninterface IHatsModuleFactory {\n error HatsModuleFactory_ModuleAlreadyDeployed(\n address implementation,\n uint256 hatId,\n bytes otherImmutableArgs,\n uint256 saltNonce\n );\n\n error BatchArrayLengthMismatch();\n\n event HatsModuleFactory_ModuleDeployed(\n address implementation,\n address instance,\n uint256 hatId,\n bytes otherImmutableArgs,\n bytes initData,\n uint256 saltNonce\n );\n\n function HATS() external view returns (address);\n\n function version() external view returns (string memory);\n\n function createHatsModule(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n bytes calldata _initData,\n uint256 _saltNonce\n ) external returns (address _instance);\n\n function batchCreateHatsModule(\n address[] calldata _implementations,\n uint256[] calldata _hatIds,\n bytes[] calldata _otherImmutableArgsArray,\n bytes[] calldata _initDataArray,\n uint256[] calldata _saltNonces\n ) external returns (bool success);\n\n function getHatsModuleAddress(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view returns (address);\n\n function deployed(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view returns (bool);\n}\n" - }, - "contracts/interfaces/hats/modules/IHatsElectionsEligibility.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.13;\n\ninterface IHatsElectionsEligibility {\n event ElectionOpened(uint128 nextTermEnd);\n event ElectionCompleted(uint128 termEnd, address[] winners);\n event NewTermStarted(uint128 termEnd);\n event Recalled(uint128 termEnd, address[] accounts);\n\n /// @notice Returns the first second after the current term ends.\n /// @dev Also serves as the id for the current term.\n function currentTermEnd() external view returns (uint128);\n\n /// @notice Returns the first second after the next term ends.\n /// @dev Also serves as the id for the next term.\n function nextTermEnd() external view returns (uint128);\n\n /// @notice Returns the election status (open or closed) for a given term end.\n /// @param termEnd The term end timestamp to query.\n function electionStatus(\n uint128 termEnd\n ) external view returns (bool isElectionOpen);\n\n /// @notice Returns whether a candidate was elected in a given term.\n /// @param termEnd The term end timestamp to query.\n /// @param candidate The address of the candidate.\n function electionResults(\n uint128 termEnd,\n address candidate\n ) external view returns (bool elected);\n\n /// @notice Returns the BALLOT_BOX_HAT constant.\n function BALLOT_BOX_HAT() external pure returns (uint256);\n\n /// @notice Returns the ADMIN_HAT constant.\n function ADMIN_HAT() external pure returns (uint256);\n\n /**\n * @notice Submit the results of an election for a specified term.\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\n * @param _termEnd The id of the term for which the election results are being submitted.\n * @param _winners The addresses of the winners of the election.\n */\n function elect(uint128 _termEnd, address[] calldata _winners) external;\n\n /**\n * @notice Submit the results of a recall election for a specified term.\n * @dev Only callable by the wearer(s) of the BALLOT_BOX_HAT.\n * @param _termEnd The id of the term for which the recall results are being submitted.\n * @param _recallees The addresses to be recalled.\n */\n function recall(uint128 _termEnd, address[] calldata _recallees) external;\n\n /**\n * @notice Set the next term and open the election for it.\n * @dev Only callable by the wearer(s) of the ADMIN_HAT.\n * @param _newTermEnd The id of the term that will be opened.\n */\n function setNextTerm(uint128 _newTermEnd) external;\n\n /**\n * @notice Start the next term, updating the current term.\n * @dev Can be called by anyone, but will revert if conditions are not met.\n */\n function startNextTerm() external;\n\n /**\n * @notice Determine the eligibility and standing of a wearer for a hat.\n * @param _wearer The address of the hat wearer.\n * @param _hatId The ID of the hat.\n * @return eligible True if the wearer is eligible for the hat.\n * @return standing True if the wearer is in good standing.\n */\n function getWearerStatus(\n address _wearer,\n uint256 _hatId\n ) external view returns (bool eligible, bool standing);\n}\n" - }, - "contracts/interfaces/IDecentAutonomousAdmin.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {IHats} from \"./hats/IHats.sol\";\n\ninterface IDecentAutonomousAdmin {\n error NotCurrentWearer();\n struct TriggerStartArgs {\n address currentWearer;\n IHats hatsProtocol;\n uint256 hatId;\n address nominatedWearer;\n }\n\n function triggerStartNextTerm(TriggerStartArgs calldata args) external;\n}\n" - }, - "contracts/interfaces/IERC6551Registry.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" - }, - "contracts/interfaces/sablier/IAdminable.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\n/// @title IAdminable\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\n/// in the constructor.\ninterface IAdminable {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin is transferred.\n /// @param oldAdmin The address of the old admin.\n /// @param newAdmin The address of the new admin.\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice The address of the admin account or contract.\n function admin() external view returns (address);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Transfers the contract admin to a new address.\n ///\n /// @dev Notes:\n /// - Does not revert if the admin is the same.\n /// - This function can potentially leave the contract without an admin, thereby removing any\n /// functionality that is only available to the admin.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newAdmin The address of the new admin.\n function transferAdmin(address newAdmin) external;\n}\n" - }, - "contracts/interfaces/sablier/IERC4096.sol": { - "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/interfaces/IERC165.sol\";\nimport {IERC721} from \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\n/// @title ERC-721 Metadata Update Extension\ninterface IERC4906 is IERC165, IERC721 {\n /// @dev This event emits when the metadata of a token is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFT.\n event MetadataUpdate(uint256 _tokenId);\n\n /// @dev This event emits when the metadata of a range of tokens is changed.\n /// So that the third-party platforms such as NFT market could\n /// timely update the images and related attributes of the NFTs.\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\n}\n" - }, - "contracts/interfaces/sablier/ISablierV2Lockup.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC4906} from \"./IERC4096.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\nimport {Lockup} from \"./types/DataTypes.sol\";\nimport {IAdminable} from \"./IAdminable.sol\";\nimport {ISablierV2NFTDescriptor} from \"./ISablierV2NFTDescriptor.sol\";\n\n/// @title ISablierV2Lockup\n/// @notice Common logic between all Sablier V2 Lockup contracts.\ninterface ISablierV2Lockup is\n IAdminable, // 0 inherited components\n IERC4906, // 2 inherited components\n IERC721Metadata // 2 inherited components\n{\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\n /// @param admin The address of the current contract admin.\n /// @param recipient The address of the recipient contract put on the allowlist.\n event AllowToHook(address indexed admin, address recipient);\n\n /// @notice Emitted when a stream is canceled.\n /// @param streamId The ID of the stream.\n /// @param sender The address of the stream's sender.\n /// @param recipient The address of the stream's recipient.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\n /// decimals.\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\n /// asset's decimals.\n event CancelLockupStream(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n IERC20 indexed asset,\n uint128 senderAmount,\n uint128 recipientAmount\n );\n\n /// @notice Emitted when a sender gives up the right to cancel a stream.\n /// @param streamId The ID of the stream.\n event RenounceLockupStream(uint256 indexed streamId);\n\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\n /// @param admin The address of the current contract admin.\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n event SetNFTDescriptor(\n address indexed admin,\n ISablierV2NFTDescriptor oldNFTDescriptor,\n ISablierV2NFTDescriptor newNFTDescriptor\n );\n\n /// @notice Emitted when assets are withdrawn from a stream.\n /// @param streamId The ID of the stream.\n /// @param to The address that has received the withdrawn assets.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\n event WithdrawFromLockupStream(\n uint256 indexed streamId,\n address indexed to,\n IERC20 indexed asset,\n uint128 amount\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\n\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getDepositedAmount(\n uint256 streamId\n ) external view returns (uint128 depositedAmount);\n\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getEndTime(\n uint256 streamId\n ) external view returns (uint40 endTime);\n\n /// @notice Retrieves the stream's recipient.\n /// @dev Reverts if the NFT has been burned.\n /// @param streamId The stream ID for the query.\n function getRecipient(\n uint256 streamId\n ) external view returns (address recipient);\n\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\n /// decimals. This amount is always zero unless the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getRefundedAmount(\n uint256 streamId\n ) external view returns (uint128 refundedAmount);\n\n /// @notice Retrieves the stream's sender.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getSender(uint256 streamId) external view returns (address sender);\n\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getStartTime(\n uint256 streamId\n ) external view returns (uint40 startTime);\n\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getWithdrawnAmount(\n uint256 streamId\n ) external view returns (uint128 withdrawnAmount);\n\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\n /// when a stream is canceled or when assets are withdrawn.\n /// @dev See {ISablierLockupRecipient} for more information.\n function isAllowedToHook(\n address recipient\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\n /// flag is always `false`.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCancelable(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isCold(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is depleted.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isDepleted(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream exists.\n /// @dev Does not revert if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isStream(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isTransferable(\n uint256 streamId\n ) external view returns (bool result);\n\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function isWarm(uint256 streamId) external view returns (bool result);\n\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\n /// number where 1e18 is 100%.\n /// @dev This value is hard coded as a constant.\n function MAX_BROKER_FEE() external view returns (UD60x18);\n\n /// @notice Counter for stream IDs, used in the create functions.\n function nextStreamId() external view returns (uint256);\n\n /// @notice Contract that generates the non-fungible token URI.\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\n\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\n /// of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function refundableAmountOf(\n uint256 streamId\n ) external view returns (uint128 refundableAmount);\n\n /// @notice Retrieves the stream's status.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function statusOf(\n uint256 streamId\n ) external view returns (Lockup.Status status);\n\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\n /// @dev Reverts if `streamId` references a null stream.\n ///\n /// Notes:\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\n /// to the total amount withdrawn.\n ///\n /// @param streamId The stream ID for the query.\n function streamedAmountOf(\n uint256 streamId\n ) external view returns (uint128 streamedAmount);\n\n /// @notice Retrieves a flag indicating whether the stream was canceled.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function wasCanceled(uint256 streamId) external view returns (bool result);\n\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\n /// decimals.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function withdrawableAmountOf(\n uint256 streamId\n ) external view returns (uint128 withdrawableAmount);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\n ///\n /// @dev Emits an {AllowToHook} event.\n ///\n /// Notes:\n /// - Does not revert if the contract is already on the allowlist.\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n /// - `recipient` must have a non-zero code size.\n /// - `recipient` must implement {ISablierLockupRecipient}.\n ///\n /// @param recipient The address of the contract to allow for hooks.\n function allowToHook(address recipient) external;\n\n /// @notice Burns the NFT associated with the stream.\n ///\n /// @dev Emits a {Transfer} event.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a depleted stream.\n /// - The NFT must exist.\n /// - `msg.sender` must be either the NFT owner or an approved third party.\n ///\n /// @param streamId The ID of the stream NFT to burn.\n function burn(uint256 streamId) external;\n\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\n ///\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\n /// stream is marked as depleted.\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - The stream must be warm and cancelable.\n /// - `msg.sender` must be the stream's sender.\n ///\n /// @param streamId The ID of the stream to cancel.\n function cancel(uint256 streamId) external;\n\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\n ///\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - Refer to the notes in {cancel}.\n ///\n /// Requirements:\n /// - All requirements from {cancel} must be met for each stream.\n ///\n /// @param streamIds The IDs of the streams to cancel.\n function cancelMultiple(uint256[] calldata streamIds) external;\n\n /// @notice Removes the right of the stream's sender to cancel the stream.\n ///\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This is an irreversible operation.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must reference a warm stream.\n /// - `msg.sender` must be the stream's sender.\n /// - The stream must be cancelable.\n ///\n /// @param streamId The ID of the stream to renounce.\n function renounce(uint256 streamId) external;\n\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\n ///\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\n ///\n /// Notes:\n /// - Does not revert if the NFT descriptor is the same.\n ///\n /// Requirements:\n /// - `msg.sender` must be the contract admin.\n ///\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\n function setNFTDescriptor(\n ISablierV2NFTDescriptor newNFTDescriptor\n ) external;\n\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `streamId` must not reference a null or depleted stream.\n /// - `to` must not be the zero address.\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\n function withdraw(uint256 streamId, address to, uint128 amount) external;\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\n ///\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\n ///\n /// Notes:\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - Refer to the requirements in {withdraw}.\n ///\n /// @param streamId The ID of the stream to withdraw from.\n /// @param to The address receiving the withdrawn assets.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\n /// NFT to `newRecipient`.\n ///\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\n ///\n /// Notes:\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\n /// - Refer to the notes in {withdraw}.\n ///\n /// Requirements:\n /// - `msg.sender` must be the stream's recipient.\n /// - Refer to the requirements in {withdraw}.\n /// - Refer to the requirements in {IERC721.transferFrom}.\n ///\n /// @param streamId The ID of the stream NFT to transfer.\n /// @param newRecipient The address of the new owner of the stream NFT.\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\n function withdrawMaxAndTransfer(\n uint256 streamId,\n address newRecipient\n ) external returns (uint128 withdrawnAmount);\n\n /// @notice Withdraws assets from streams to the recipient of each stream.\n ///\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\n ///\n /// Notes:\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - There must be an equal number of `streamIds` and `amounts`.\n /// - Each stream ID in the array must not reference a null or depleted stream.\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\n ///\n /// @param streamIds The IDs of the streams to withdraw from.\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\n function withdrawMultiple(\n uint256[] calldata streamIds,\n uint128[] calldata amounts\n ) external;\n}\n" - }, - "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport {Lockup, LockupLinear} from \"./types/DataTypes.sol\";\nimport {ISablierV2Lockup} from \"./ISablierV2Lockup.sol\";\n\n/// @title ISablierV2LockupLinear\n/// @notice Creates and manages Lockup streams with a linear distribution function.\ninterface ISablierV2LockupLinear is ISablierV2Lockup {\n /*//////////////////////////////////////////////////////////////////////////\n EVENTS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Emitted when a stream is created.\n /// @param streamId The ID of the newly created stream.\n /// @param funder The address which funded the stream.\n /// @param sender The address distributing the assets, which will have the ability to cancel the stream.\n /// @param recipient The address receiving the assets.\n /// @param amounts Struct encapsulating (i) the deposit amount, and (ii) the broker fee amount, both denoted\n /// in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Boolean indicating whether the stream will be cancelable or not.\n /// @param transferable Boolean indicating whether the stream NFT is transferable or not.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker The address of the broker who has helped create the stream, e.g. a front-end website.\n event CreateLockupLinearStream(\n uint256 streamId,\n address funder,\n address indexed sender,\n address indexed recipient,\n Lockup.CreateAmounts amounts,\n IERC20 indexed asset,\n bool cancelable,\n bool transferable,\n LockupLinear.Timestamps timestamps,\n address broker\n );\n\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Retrieves the stream's cliff time, which is a Unix timestamp. A value of zero means there\n /// is no cliff.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n function getCliffTime(\n uint256 streamId\n ) external view returns (uint40 cliffTime);\n\n /// @notice Retrieves the full stream details.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n /// @return stream See the documentation in {DataTypes}.\n function getStream(\n uint256 streamId\n ) external view returns (LockupLinear.StreamLL memory stream);\n\n /// @notice Retrieves the stream's start, cliff and end timestamps.\n /// @dev Reverts if `streamId` references a null stream.\n /// @param streamId The stream ID for the query.\n /// @return timestamps See the documentation in {DataTypes}.\n function getTimestamps(\n uint256 streamId\n ) external view returns (LockupLinear.Timestamps memory timestamps);\n\n /*//////////////////////////////////////////////////////////////////////////\n NON-CONSTANT FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n /// @notice Creates a stream by setting the start time to `block.timestamp`, and the end time to\n /// the sum of `block.timestamp` and `params.durations.total`. The stream is funded by `msg.sender` and is wrapped\n /// in an ERC-721 NFT.\n ///\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\n ///\n /// Requirements:\n /// - All requirements in {createWithTimestamps} must be met for the calculated parameters.\n ///\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\n /// @return streamId The ID of the newly created stream.\n function createWithDurations(\n LockupLinear.CreateWithDurations calldata params\n ) external returns (uint256 streamId);\n\n /// @notice Creates a stream with the provided start time and end time. The stream is funded by `msg.sender` and is\n /// wrapped in an ERC-721 NFT.\n ///\n /// @dev Emits a {Transfer} and {CreateLockupLinearStream} event.\n ///\n /// Notes:\n /// - A cliff time of zero means there is no cliff.\n /// - As long as the times are ordered, it is not an error for the start or the cliff time to be in the past.\n ///\n /// Requirements:\n /// - Must not be delegate called.\n /// - `params.totalAmount` must be greater than zero.\n /// - If set, `params.broker.fee` must not be greater than `MAX_BROKER_FEE`.\n /// - `params.timestamps.start` must be greater than zero and less than `params.timestamps.end`.\n /// - If set, `params.timestamps.cliff` must be greater than `params.timestamps.start` and less than\n /// `params.timestamps.end`.\n /// - `params.timestamps.end` must be in the future.\n /// - `params.recipient` must not be the zero address.\n /// - `msg.sender` must have allowed this contract to spend at least `params.totalAmount` assets.\n ///\n /// @param params Struct encapsulating the function parameters, which are documented in {DataTypes}.\n /// @return streamId The ID of the newly created stream.\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" - }, - "contracts/interfaces/sablier/ISablierV2NFTDescriptor.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC721Metadata} from \"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\";\n\n/// @title ISablierV2NFTDescriptor\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\n/// @dev Inspired by Uniswap V3 Positions NFTs.\ninterface ISablierV2NFTDescriptor {\n /// @notice Produces the URI describing a particular stream NFT.\n /// @dev This is a data URI with the JSON contents directly inlined.\n /// @param sablier The address of the Sablier contract the stream was created in.\n /// @param streamId The ID of the stream for which to produce a description.\n /// @return uri The URI of the ERC721-compliant metadata.\n function tokenURI(\n IERC721Metadata sablier,\n uint256 streamId\n ) external view returns (string memory uri);\n}\n" - }, - "contracts/interfaces/sablier/types/DataTypes.sol": { - "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity >=0.8.22;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {UD2x18} from \"@prb/math/src/UD2x18.sol\";\nimport {UD60x18} from \"@prb/math/src/UD60x18.sol\";\n\n// DataTypes.sol\n//\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\n//\n// - Lockup\n// - LockupDynamic\n// - LockupLinear\n// - LockupTranched\n//\n// You will notice that some structs contain \"slot\" annotations - they are used to indicate the\n// storage layout of the struct. It is more gas efficient to group small data types together so\n// that they fit in a single 32-byte slot.\n\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\n/// @param account The address receiving the broker's fee.\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\nstruct Broker {\n address account;\n UD60x18 fee;\n}\n\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\nlibrary Lockup {\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\n /// decimals.\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\n /// saves gas.\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\n /// @param withdrawn The cumulative amount withdrawn from the stream.\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\n struct Amounts {\n // slot 0\n uint128 deposited;\n uint128 withdrawn;\n // slot 1\n uint128 refunded;\n }\n\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\n /// asset's decimals.\n /// @param deposit The amount to deposit in the stream.\n /// @param brokerFee The broker fee amount.\n struct CreateAmounts {\n uint128 deposit;\n uint128 brokerFee;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\n /// @dev The fields are arranged like this to save gas via tight variable packing.\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param endTime The Unix timestamp indicating the stream's end.\n /// @param isCancelable Boolean indicating if the stream is cancelable.\n /// @param wasCanceled Boolean indicating if the stream was canceled.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param isDepleted Boolean indicating if the stream is depleted.\n /// @param isStream Boolean indicating if the struct entity exists.\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\n /// asset's decimals.\n struct Stream {\n // slot 0\n address sender;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n // slot 1\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n // slot 2 and 3\n Lockup.Amounts amounts;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\nlibrary LockupDynamic {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n SegmentWithDuration[] segments;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param segments Segments used to compose the dynamic distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Segment[] segments;\n Broker broker;\n }\n\n /// @notice Segment struct used in the Lockup Dynamic stream.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param timestamp The Unix timestamp indicating the segment's end.\n struct Segment {\n // slot 0\n uint128 amount;\n UD2x18 exponent;\n uint40 timestamp;\n }\n\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\n /// @param duration The time difference in seconds between the segment and the previous one.\n struct SegmentWithDuration {\n uint128 amount;\n UD2x18 exponent;\n uint40 duration;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\n struct StreamLD {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Segment[] segments;\n }\n\n /// @notice Struct encapsulating the LockupDynamic timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\nlibrary LockupLinear {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Durations durations;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\n /// Unix timestamps.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the cliff duration and the total duration.\n /// @param cliff The cliff duration in seconds.\n /// @param total The total duration in seconds.\n struct Durations {\n uint40 cliff;\n uint40 total;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\n struct StreamLL {\n address sender;\n address recipient;\n uint40 startTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n uint40 endTime;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n uint40 cliffTime;\n }\n\n /// @notice Struct encapsulating the LockupLinear timestamps.\n /// @param start The Unix timestamp for the stream's start.\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\n /// @param end The Unix timestamp for the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n}\n\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\nlibrary LockupTranched {\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithDurations {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n TrancheWithDuration[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\n /// the same as `msg.sender`.\n /// @param recipient The address receiving the assets.\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\n /// broker fee, denoted in units of the asset's decimals.\n /// @param asset The contract address of the ERC-20 asset to be distributed.\n /// @param cancelable Indicates if the stream is cancelable.\n /// @param transferable Indicates if the stream NFT is transferable.\n /// @param startTime The Unix timestamp indicating the stream's start.\n /// @param tranches Tranches used to compose the tranched distribution function.\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n uint40 startTime;\n Tranche[] tranches;\n Broker broker;\n }\n\n /// @notice Struct encapsulating the full details of a stream.\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\n struct StreamLT {\n address sender;\n address recipient;\n uint40 startTime;\n uint40 endTime;\n bool isCancelable;\n bool wasCanceled;\n IERC20 asset;\n bool isDepleted;\n bool isStream;\n bool isTransferable;\n Lockup.Amounts amounts;\n Tranche[] tranches;\n }\n\n /// @notice Struct encapsulating the LockupTranched timestamps.\n /// @param start The Unix timestamp indicating the stream's start.\n /// @param end The Unix timestamp indicating the stream's end.\n struct Timestamps {\n uint40 start;\n uint40 end;\n }\n\n /// @notice Tranche struct used in the Lockup Tranched stream.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param timestamp The Unix timestamp indicating the tranche's end.\n struct Tranche {\n // slot 0\n uint128 amount;\n uint40 timestamp;\n }\n\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\n /// @param duration The time difference in seconds between the tranche and the previous one.\n struct TrancheWithDuration {\n uint128 amount;\n uint40 duration;\n }\n}\n" - }, - "contracts/mocks/ERC6551Registry.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev The registry MUST emit the ERC6551AccountCreated event upon successful account creation.\n */\n event ERC6551AccountCreated(\n address account,\n address indexed implementation,\n bytes32 salt,\n uint256 chainId,\n address indexed tokenContract,\n uint256 indexed tokenId\n );\n\n /**\n * @dev The registry MUST revert with AccountCreationFailed error if the create2 operation fails.\n */\n error AccountCreationFailed();\n\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n\n /**\n * @dev Returns the computed token bound account address for a non-fungible token.\n *\n * @return account The address of the token bound account\n */\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address account);\n}\n\ncontract ERC6551Registry is IERC6551Registry {\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address) {\n assembly {\n // Memory Layout:\n // ----\n // 0x00 0xff (1 byte)\n // 0x01 registry (address) (20 bytes)\n // 0x15 salt (bytes32) (32 bytes)\n // 0x35 Bytecode Hash (bytes32) (32 bytes)\n // ----\n // 0x55 ERC-1167 Constructor + Header (20 bytes)\n // 0x69 implementation (address) (20 bytes)\n // 0x5D ERC-1167 Footer (15 bytes)\n // 0x8C salt (uint256) (32 bytes)\n // 0xAC chainId (uint256) (32 bytes)\n // 0xCC tokenContract (address) (32 bytes)\n // 0xEC tokenId (uint256) (32 bytes)\n\n // Silence unused variable warnings\n pop(chainId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Compute account address\n let computed := keccak256(0x00, 0x55)\n\n // If the account has not yet been deployed\n if iszero(extcodesize(computed)) {\n // Deploy account contract\n let deployed := create2(0, 0x55, 0xb7, salt)\n\n // Revert if the deployment fails\n if iszero(deployed) {\n mstore(0x00, 0x20188a59) // `AccountCreationFailed()`\n revert(0x1c, 0x04)\n }\n\n // Store account address in memory before salt and chainId\n mstore(0x6c, deployed)\n\n // Emit the ERC6551AccountCreated event\n log4(\n 0x6c,\n 0x60,\n // `ERC6551AccountCreated(address,address,bytes32,uint256,address,uint256)`\n 0x79f19b3655ee38b1ce526556b7731a20c8f218fbda4a3990b6cc4172fdf88722,\n implementation,\n tokenContract,\n tokenId\n )\n\n // Return the account address\n return(0x6c, 0x20)\n }\n\n // Otherwise, return the computed account address\n mstore(0x00, shr(96, shl(96, computed)))\n return(0x00, 0x20)\n }\n }\n\n function account(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external view returns (address) {\n assembly {\n // Silence unused variable warnings\n pop(chainId)\n pop(tokenContract)\n pop(tokenId)\n\n // Copy bytecode + constant data to memory\n calldatacopy(0x8c, 0x24, 0x80) // salt, chainId, tokenContract, tokenId\n mstore(0x6c, 0x5af43d82803e903d91602b57fd5bf3) // ERC-1167 footer\n mstore(0x5d, implementation) // implementation\n mstore(0x49, 0x3d60ad80600a3d3981f3363d3d373d3d3d363d73) // ERC-1167 constructor + header\n\n // Copy create2 computation data to memory\n mstore8(0x00, 0xff) // 0xFF\n mstore(0x35, keccak256(0x55, 0xb7)) // keccak256(bytecode)\n mstore(0x01, shl(96, address())) // registry address\n mstore(0x15, salt) // salt\n\n // Store computed account address in memory\n mstore(0x00, shr(96, shl(96, keccak256(0x00, 0x55))))\n\n // Return computed account address\n return(0x00, 0x20)\n }\n }\n}\n" - }, - "contracts/mocks/MockContract.sol": { - "content": "//SPDX-License-Identifier: Unlicense\n\npragma solidity ^0.8.19;\n\n/**\n * Mock contract for testing\n */\ncontract MockContract {\n event DidSomething(string message);\n\n error Reverting();\n\n function doSomething() public {\n doSomethingWithParam(\"doSomething()\");\n }\n\n function doSomethingWithParam(string memory _message) public {\n emit DidSomething(_message);\n }\n\n function returnSomething(string memory _s)\n external\n pure\n returns (string memory)\n {\n return _s;\n }\n\n function revertSomething() external pure {\n revert Reverting();\n }\n}\n" - }, - "contracts/mocks/MockDecentHatsUtils.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\nimport {DecentHatsUtils} from \"../DecentHatsUtils.sol\";\nimport {IHats} from \"../interfaces/hats/IHats.sol\";\nimport {IERC6551Registry} from \"../interfaces/IERC6551Registry.sol\";\nimport {IHatsModuleFactory} from \"../interfaces/hats/IHatsModuleFactory.sol\";\n\ncontract MockDecentHatsUtils is DecentHatsUtils {\n // Expose the internal _processHat function for testing\n function processHat(\n IHats hatsProtocol,\n IERC6551Registry erc6551Registry,\n address hatsAccountImplementation,\n uint256 topHatId,\n address topHatAccount,\n IHatsModuleFactory hatsModuleFactory,\n address hatsElectionsEligibilityImplementation,\n uint256 adminHatId,\n HatParams memory hat\n ) external {\n _processHat(\n hatsProtocol,\n erc6551Registry,\n hatsAccountImplementation,\n topHatId,\n topHatAccount,\n hatsModuleFactory,\n hatsElectionsEligibilityImplementation,\n adminHatId,\n hat\n );\n }\n}\n" - }, - "contracts/mocks/MockHatsElectionEligibility.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\nimport {IHatsElectionsEligibility} from \"../interfaces/hats/modules/IHatsElectionsEligibility.sol\";\n\ncontract MockHatsElectionsEligibility is IHatsElectionsEligibility {\n function currentTermEnd() external view returns (uint128) {}\n\n function nextTermEnd() external view returns (uint128) {}\n\n function electionStatus(\n uint128 termEnd\n ) external view returns (bool isElectionOpen) {}\n\n function electionResults(\n uint128 termEnd,\n address candidate\n ) external view returns (bool elected) {}\n\n function BALLOT_BOX_HAT() external pure returns (uint256) {}\n\n function ADMIN_HAT() external pure returns (uint256) {}\n\n function elect(uint128 _termEnd, address[] calldata _winners) external {}\n\n function recall(uint128 _termEnd, address[] calldata _recallees) external {}\n\n function setNextTerm(uint128 _newTermEnd) external {}\n\n function startNextTerm() external {}\n\n function getWearerStatus(\n address,\n uint256\n ) external pure returns (bool eligible, bool standing) {\n return (true, true);\n }\n}\n" - }, - "contracts/mocks/MockHatsModuleFactory.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport {IHatsModuleFactory} from \"../interfaces/hats/IHatsModuleFactory.sol\";\nimport {MockHatsElectionsEligibility} from \"./MockHatsElectionEligibility.sol\";\n\ncontract MockHatsModuleFactory is IHatsModuleFactory {\n function createHatsModule(\n address,\n uint256,\n bytes calldata,\n bytes calldata,\n uint256\n ) external override returns (address _instance) {\n // Deploy a new instance of MockHatsElectionEligibility\n MockHatsElectionsEligibility newModule = new MockHatsElectionsEligibility();\n _instance = address(newModule);\n }\n\n function getHatsModuleAddress(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view returns (address) {}\n\n function HATS() external view override returns (address) {}\n\n function version() external view override returns (string memory) {}\n\n function batchCreateHatsModule(\n address[] calldata _implementations,\n uint256[] calldata _hatIds,\n bytes[] calldata _otherImmutableArgsArray,\n bytes[] calldata _initDataArray,\n uint256[] calldata _saltNonces\n ) external override returns (bool success) {}\n\n function deployed(\n address _implementation,\n uint256 _hatId,\n bytes calldata _otherImmutableArgs,\n uint256 _saltNonce\n ) external view override returns (bool) {}\n}\n" - }, - "contracts/mocks/MockLockupLinear.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary MockLockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n\n struct Stream {\n address sender;\n uint40 startTime;\n uint40 endTime;\n uint40 cliffTime;\n bool cancelable;\n bool wasCanceled;\n address asset;\n bool transferable;\n uint128 totalAmount;\n address recipient;\n }\n\n /// @notice Enum representing the different statuses of a stream.\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\n enum Status {\n PENDING,\n STREAMING,\n SETTLED,\n CANCELED,\n DEPLETED\n }\n}\n" - }, - "contracts/mocks/MockSablierV2LockupLinear.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.22;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {ISablierV2LockupLinear} from \"../interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {MockLockupLinear} from \"./MockLockupLinear.sol\";\n\ncontract MockSablierV2LockupLinear {\n mapping(uint256 => MockLockupLinear.Stream) public streams;\n uint256 public nextStreamId = 1;\n\n // Add this event declaration at the contract level\n event StreamCreated(\n uint256 streamId,\n address indexed sender,\n address indexed recipient,\n uint128 totalAmount,\n address indexed asset,\n bool cancelable,\n bool transferable,\n uint40 startTime,\n uint40 cliffTime,\n uint40 endTime\n );\n\n function createWithTimestamps(\n MockLockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId) {\n require(\n params.asset.transferFrom(\n msg.sender,\n address(this),\n params.totalAmount\n ),\n \"Token transfer failed\"\n );\n\n streamId = nextStreamId++;\n streams[streamId] = MockLockupLinear.Stream({\n sender: params.sender,\n recipient: params.recipient,\n totalAmount: params.totalAmount,\n asset: address(params.asset),\n cancelable: params.cancelable,\n wasCanceled: false,\n transferable: params.transferable,\n startTime: params.timestamps.start,\n cliffTime: params.timestamps.cliff,\n endTime: params.timestamps.end\n });\n\n // Emit the StreamCreated event\n emit StreamCreated(\n streamId,\n params.sender,\n params.recipient,\n params.totalAmount,\n address(params.asset),\n params.cancelable,\n params.transferable,\n params.timestamps.start,\n params.timestamps.cliff,\n params.timestamps.end\n );\n\n return streamId;\n }\n\n function getStream(\n uint256 streamId\n ) external view returns (MockLockupLinear.Stream memory) {\n return streams[streamId];\n }\n\n function withdrawableAmountOf(\n uint256 streamId\n ) public view returns (uint128) {\n MockLockupLinear.Stream memory stream = streams[streamId];\n if (block.timestamp <= stream.startTime) {\n return 0;\n }\n if (block.timestamp >= stream.endTime) {\n return stream.totalAmount;\n }\n return\n uint128(\n (stream.totalAmount * (block.timestamp - stream.startTime)) /\n (stream.endTime - stream.startTime)\n );\n }\n\n function withdrawMax(\n uint256 streamId,\n address to\n ) external returns (uint128 withdrawnAmount) {\n withdrawnAmount = withdrawableAmountOf(streamId);\n MockLockupLinear.Stream storage stream = streams[streamId];\n\n require(\n msg.sender == stream.recipient,\n \"Only recipient can call withdraw\"\n );\n require(\n withdrawnAmount <= withdrawableAmountOf(streamId),\n \"Insufficient withdrawable amount\"\n );\n\n stream.totalAmount -= withdrawnAmount;\n IERC20(stream.asset).transfer(to, withdrawnAmount);\n }\n\n function cancel(uint256 streamId) external {\n MockLockupLinear.Stream memory stream = streams[streamId];\n require(stream.cancelable, \"Stream is not cancelable\");\n require(msg.sender == stream.sender, \"Only sender can cancel\");\n\n uint128 withdrawableAmount = withdrawableAmountOf(streamId);\n uint128 refundAmount = stream.totalAmount - withdrawableAmount;\n\n streams[streamId].wasCanceled = true;\n\n if (withdrawableAmount > 0) {\n IERC20(stream.asset).transfer(stream.recipient, withdrawableAmount);\n }\n if (refundAmount > 0) {\n IERC20(stream.asset).transfer(stream.sender, refundAmount);\n }\n }\n\n function isCancelable(uint256 streamId) external view returns (bool) {\n return streams[streamId].cancelable;\n }\n\n /// @dev Retrieves the stream's status without performing a null check.\n function statusOf(\n uint256 streamId\n ) public view returns (MockLockupLinear.Status) {\n uint256 withdrawableAmount = withdrawableAmountOf(streamId);\n if (withdrawableAmount == 0) {\n return MockLockupLinear.Status.DEPLETED;\n } else if (streams[streamId].wasCanceled) {\n return MockLockupLinear.Status.CANCELED;\n }\n\n if (block.timestamp < streams[streamId].startTime) {\n return MockLockupLinear.Status.PENDING;\n }\n\n if (block.timestamp < streams[streamId].endTime) {\n return MockLockupLinear.Status.STREAMING;\n } else {\n return MockLockupLinear.Status.SETTLED;\n }\n }\n}\n" - } - }, - "settings": { - "optimizer": { - "enabled": true, - "runs": 200 - }, - "evmVersion": "paris", - "outputSelection": { - "*": { - "*": [ - "abi", - "evm.bytecode", - "evm.deployedBytecode", - "evm.methodIdentifiers", - "metadata", - "devdoc", - "userdoc", - "storageLayout", - "evm.gasEstimates" - ], - "": [ - "ast" - ] - } - }, - "metadata": { - "useLiteralContent": true - } - } -} \ No newline at end of file From 440d4c573ab6035d682b8b9df17d9b49df04a55a Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 14:59:09 -0400 Subject: [PATCH 187/206] Put this file back --- .../DecentSablierStreamManagement.json | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 deployments/sepolia/DecentSablierStreamManagement.json diff --git a/deployments/sepolia/DecentSablierStreamManagement.json b/deployments/sepolia/DecentSablierStreamManagement.json new file mode 100644 index 00000000..3779fae4 --- /dev/null +++ b/deployments/sepolia/DecentSablierStreamManagement.json @@ -0,0 +1,100 @@ +{ + "address": "0x5874bf327bA5b78b2371b13eB414B66179591d34", + "abi": [ + { + "inputs": [], + "name": "NAME", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + } + ], + "name": "cancelStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISablierV2Lockup", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "recipientHatAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "streamId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "withdrawMaxFromStream", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", + "receipt": { + "to": null, + "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", + "contractAddress": "0x5874bf327bA5b78b2371b13eB414B66179591d34", + "transactionIndex": 72, + "gasUsed": "384441", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x2d90032ee5f61b968f6e38065b8dab930b88bb292edc0059448acc5e02903a4a", + "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", + "logs": [], + "blockNumber": 6850325, + "cumulativeGasUsed": "8716271", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "4511b61209438ca20d2458493e70bb24", + "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", + "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file From 0f70bd044db814918cb2b404e16c326b787f6dd3 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 15:04:11 -0400 Subject: [PATCH 188/206] Delete old DecentHats_0_1_0 and DecentSablierStreamManagement artifacts from all networks --- deployments/base/DecentHats_0_1_0.json | 504 ----------------- .../base/DecentSablierStreamManagement.json | 100 ---- deployments/mainnet/DecentHats_0_1_0.json | 504 ----------------- .../DecentSablierStreamManagement.json | 100 ---- deployments/optimism/DecentHats_0_1_0.json | 504 ----------------- .../DecentSablierStreamManagement.json | 100 ---- deployments/polygon/DecentHats_0_1_0.json | 520 ------------------ .../DecentSablierStreamManagement.json | 116 ---- deployments/sepolia/DecentHats_0_1_0.json | 504 ----------------- .../DecentSablierStreamManagement.json | 100 ---- 10 files changed, 3052 deletions(-) delete mode 100644 deployments/base/DecentHats_0_1_0.json delete mode 100644 deployments/base/DecentSablierStreamManagement.json delete mode 100644 deployments/mainnet/DecentHats_0_1_0.json delete mode 100644 deployments/mainnet/DecentSablierStreamManagement.json delete mode 100644 deployments/optimism/DecentHats_0_1_0.json delete mode 100644 deployments/optimism/DecentSablierStreamManagement.json delete mode 100644 deployments/polygon/DecentHats_0_1_0.json delete mode 100644 deployments/polygon/DecentSablierStreamManagement.json delete mode 100644 deployments/sepolia/DecentHats_0_1_0.json delete mode 100644 deployments/sepolia/DecentSablierStreamManagement.json diff --git a/deployments/base/DecentHats_0_1_0.json b/deployments/base/DecentHats_0_1_0.json deleted file mode 100644 index ec1bdb20..00000000 --- a/deployments/base/DecentHats_0_1_0.json +++ /dev/null @@ -1,504 +0,0 @@ -{ - "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "keyValuePairs", - "type": "address" - }, - { - "internalType": "string", - "name": "topHatDetails", - "type": "string" - }, - { - "internalType": "string", - "name": "topHatImageURI", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "adminHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat[]", - "name": "hats", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.CreateTreeParams", - "name": "params", - "type": "tuple" - } - ], - "name": "createAndDeclareTree", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "adminHatId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "hat", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "topHatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "topHatAccount", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "createRoleHat", - "outputs": [ - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "accountAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getSalt", - "outputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0x5e1f773df67fb54ba7cf1b3b500c8bf99b45f2c4bc0442f53ffb9e2b42738a00", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", - "transactionIndex": 67, - "gasUsed": "1243979", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4972942095f87c4710d5794d86dd19283408255356cabe89217a00cf41239cf8", - "transactionHash": "0x5e1f773df67fb54ba7cf1b3b500c8bf99b45f2c4bc0442f53ffb9e2b42738a00", - "logs": [], - "blockNumber": 21538074, - "cumulativeGasUsed": "14620525", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 4, - "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "devdoc": { - "kind": "dev", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/base/DecentSablierStreamManagement.json b/deployments/base/DecentSablierStreamManagement.json deleted file mode 100644 index a4695b56..00000000 --- a/deployments/base/DecentSablierStreamManagement.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "address": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - } - ], - "name": "cancelStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "recipientHatAccount", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "withdrawMaxFromStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xe8c58dad912fb02c5477f4d221e92994a80fbc2b8d26c05da7f394582c9451bb", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", - "transactionIndex": 95, - "gasUsed": "384441", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe2639b222eafa8314a402b10a98cab3ca4ca1143cbfdf696850f1a07b2a4256a", - "transactionHash": "0xe8c58dad912fb02c5477f4d221e92994a80fbc2b8d26c05da7f394582c9451bb", - "logs": [], - "blockNumber": 20894292, - "cumulativeGasUsed": "20584732", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4511b61209438ca20d2458493e70bb24", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/mainnet/DecentHats_0_1_0.json b/deployments/mainnet/DecentHats_0_1_0.json deleted file mode 100644 index 6f619b3f..00000000 --- a/deployments/mainnet/DecentHats_0_1_0.json +++ /dev/null @@ -1,504 +0,0 @@ -{ - "address": "0x3F852ac21185E62F322F8d0Ca680b06c077280D5", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "keyValuePairs", - "type": "address" - }, - { - "internalType": "string", - "name": "topHatDetails", - "type": "string" - }, - { - "internalType": "string", - "name": "topHatImageURI", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "adminHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat[]", - "name": "hats", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.CreateTreeParams", - "name": "params", - "type": "tuple" - } - ], - "name": "createAndDeclareTree", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "adminHatId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "hat", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "topHatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "topHatAccount", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "createRoleHat", - "outputs": [ - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "accountAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getSalt", - "outputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0x1a2b34ff7f671d4a727d06ad509eca16d699e76b87c36bc0996579b9e649272e", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x3F852ac21185E62F322F8d0Ca680b06c077280D5", - "transactionIndex": 9, - "gasUsed": "1243979", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x9aac8241b655d66208a24411411b3f2b81bd4edda3d80847c6b1c46b8e71d85e", - "transactionHash": "0x1a2b34ff7f671d4a727d06ad509eca16d699e76b87c36bc0996579b9e649272e", - "logs": [], - "blockNumber": 21043134, - "cumulativeGasUsed": "2480225", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 4, - "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "devdoc": { - "kind": "dev", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/mainnet/DecentSablierStreamManagement.json b/deployments/mainnet/DecentSablierStreamManagement.json deleted file mode 100644 index 19664031..00000000 --- a/deployments/mainnet/DecentSablierStreamManagement.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "address": "0x84D96C7cD9F1Ea7da6d37054b0A6762be949df2B", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - } - ], - "name": "cancelStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "recipientHatAccount", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "withdrawMaxFromStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x1b8f61e0172a4044a4021ccd9ce6fd30095c568778c829d2d16959fd894cf7aa", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x84D96C7cD9F1Ea7da6d37054b0A6762be949df2B", - "transactionIndex": 94, - "gasUsed": "384441", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xdde1b87de37ca61887609fd8695e07b689dfd85acc88755aca2b61aeae22ded2", - "transactionHash": "0x1b8f61e0172a4044a4021ccd9ce6fd30095c568778c829d2d16959fd894cf7aa", - "logs": [], - "blockNumber": 20936434, - "cumulativeGasUsed": "8659131", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4511b61209438ca20d2458493e70bb24", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/optimism/DecentHats_0_1_0.json b/deployments/optimism/DecentHats_0_1_0.json deleted file mode 100644 index 06cee265..00000000 --- a/deployments/optimism/DecentHats_0_1_0.json +++ /dev/null @@ -1,504 +0,0 @@ -{ - "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "keyValuePairs", - "type": "address" - }, - { - "internalType": "string", - "name": "topHatDetails", - "type": "string" - }, - { - "internalType": "string", - "name": "topHatImageURI", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "adminHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat[]", - "name": "hats", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.CreateTreeParams", - "name": "params", - "type": "tuple" - } - ], - "name": "createAndDeclareTree", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "adminHatId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "hat", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "topHatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "topHatAccount", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "createRoleHat", - "outputs": [ - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "accountAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getSalt", - "outputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0x57c929ca92770fd06f0a51d038d29bfbf8790582f290fefb712c9b5a867aee84", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", - "transactionIndex": 24, - "gasUsed": "1243979", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7b3f0fd56bbfa019a8edb17cd23803cc2fdb06712a35d74474c06b09828d73c6", - "transactionHash": "0x57c929ca92770fd06f0a51d038d29bfbf8790582f290fefb712c9b5a867aee84", - "logs": [], - "blockNumber": 127133402, - "cumulativeGasUsed": "7388287", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 4, - "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "devdoc": { - "kind": "dev", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/optimism/DecentSablierStreamManagement.json b/deployments/optimism/DecentSablierStreamManagement.json deleted file mode 100644 index 5681bc6e..00000000 --- a/deployments/optimism/DecentSablierStreamManagement.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "address": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - } - ], - "name": "cancelStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "recipientHatAccount", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "withdrawMaxFromStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0xa70b0fd93d4afeb76e06826853681fb456c1c99e5005adf1904d7dce18e311bb", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x10295461bf4ad03A76Bf29d8e98bf068ec333854", - "transactionIndex": 13, - "gasUsed": "384441", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x8d4430fb1ba84139a233692228da3d47eda1e21063cbe56f4c01501a37926b2b", - "transactionHash": "0xa70b0fd93d4afeb76e06826853681fb456c1c99e5005adf1904d7dce18e311bb", - "logs": [], - "blockNumber": 126489616, - "cumulativeGasUsed": "2581689", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4511b61209438ca20d2458493e70bb24", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/polygon/DecentHats_0_1_0.json b/deployments/polygon/DecentHats_0_1_0.json deleted file mode 100644 index 4f31841f..00000000 --- a/deployments/polygon/DecentHats_0_1_0.json +++ /dev/null @@ -1,520 +0,0 @@ -{ - "address": "0xD16368a8b709cBAfd47c480607a843144Bcd27Dc", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "keyValuePairs", - "type": "address" - }, - { - "internalType": "string", - "name": "topHatDetails", - "type": "string" - }, - { - "internalType": "string", - "name": "topHatImageURI", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "adminHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat[]", - "name": "hats", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.CreateTreeParams", - "name": "params", - "type": "tuple" - } - ], - "name": "createAndDeclareTree", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "adminHatId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "hat", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "topHatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "topHatAccount", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "createRoleHat", - "outputs": [ - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "accountAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getSalt", - "outputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xD16368a8b709cBAfd47c480607a843144Bcd27Dc", - "transactionIndex": 40, - "gasUsed": "1243979", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000120004000000000000000000200000000000000000000000000000000000000000000000100000", - "blockHash": "0xd9e72f56a6a5a78cf740fa9f15bee4930ed50fcf55b112b8f6165202a874477c", - "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", - "logs": [ - { - "transactionIndex": 40, - "blockNumber": 63474684, - "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", - "address": "0x0000000000000000000000000000000000001010", - "topics": [ - "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", - "0x0000000000000000000000000000000000000000000000000000000000001010", - "0x000000000000000000000000b5ca125166c1987a35edd550e16846fa1e1d9bb3", - "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" - ], - "data": "0x00000000000000000000000000000000000000000000000000bcc837b2df4d5a0000000000000000000000000000000000000000000000003307e25cd9ef8900000000000000000000000000000000000000000000000b962f1502731c562a88000000000000000000000000000000000000000000000000324b1a2527103ba6000000000000000000000000000000000000000000000b962fd1caaacf3577e2", - "logIndex": 247, - "blockHash": "0xd9e72f56a6a5a78cf740fa9f15bee4930ed50fcf55b112b8f6165202a874477c" - } - ], - "blockNumber": 63474684, - "cumulativeGasUsed": "9341874", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 4, - "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "devdoc": { - "kind": "dev", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/polygon/DecentSablierStreamManagement.json b/deployments/polygon/DecentSablierStreamManagement.json deleted file mode 100644 index 795367d5..00000000 --- a/deployments/polygon/DecentSablierStreamManagement.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "address": "0xcd6c149b3C0FE7284005869fa15080e85887c8F1", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - } - ], - "name": "cancelStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "recipientHatAccount", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "withdrawMaxFromStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x79bc48a59de268be4623c5a7a2e419da30b95b8bb7119f60e59f097c5aa30dba", - "receipt": { - "to": null, - "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xcd6c149b3C0FE7284005869fa15080e85887c8F1", - "transactionIndex": 26, - "gasUsed": "384441", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000008000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000800100080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000100004000000000000000000200000000000000000000000000000000000000000000000100000", - "blockHash": "0x2ba2274d8334e11975c51b3ec0bb574f93ac83042f9fd1863b28b6e183999f9d", - "transactionHash": "0x79bc48a59de268be4623c5a7a2e419da30b95b8bb7119f60e59f097c5aa30dba", - "logs": [ - { - "transactionIndex": 26, - "blockNumber": 62872232, - "transactionHash": "0x79bc48a59de268be4623c5a7a2e419da30b95b8bb7119f60e59f097c5aa30dba", - "address": "0x0000000000000000000000000000000000001010", - "topics": [ - "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", - "0x0000000000000000000000000000000000000000000000000000000000001010", - "0x000000000000000000000000b5ca125166c1987a35edd550e16846fa1e1d9bb3", - "0x00000000000000000000000083d69448f88bf9c701c1b93f43e1f753d39b2632" - ], - "data": "0x0000000000000000000000000000000000000000000000000032e47e5c4a2ad2000000000000000000000000000000000000000000000000344315f1bf0ff3a9000000000000000000000000000000000000000000000ba51a4e83ca9587c9510000000000000000000000000000000000000000000000003410317362c5c8d7000000000000000000000000000000000000000000000ba51a816848f1d1f423", - "logIndex": 91, - "blockHash": "0x2ba2274d8334e11975c51b3ec0bb574f93ac83042f9fd1863b28b6e183999f9d" - } - ], - "blockNumber": 62872232, - "cumulativeGasUsed": "3140534", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4511b61209438ca20d2458493e70bb24", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/sepolia/DecentHats_0_1_0.json b/deployments/sepolia/DecentHats_0_1_0.json deleted file mode 100644 index fc9fee8b..00000000 --- a/deployments/sepolia/DecentHats_0_1_0.json +++ /dev/null @@ -1,504 +0,0 @@ -{ - "address": "0x0bEe0a447e6A5bEA8CAA0d8559A681EE16d6caCE", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "keyValuePairs", - "type": "address" - }, - { - "internalType": "string", - "name": "topHatDetails", - "type": "string" - }, - { - "internalType": "string", - "name": "topHatImageURI", - "type": "string" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "adminHat", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat[]", - "name": "hats", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.CreateTreeParams", - "name": "params", - "type": "tuple" - } - ], - "name": "createAndDeclareTree", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract IHats", - "name": "hatsProtocol", - "type": "address" - }, - { - "internalType": "uint256", - "name": "adminHatId", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint32", - "name": "maxSupply", - "type": "uint32" - }, - { - "internalType": "string", - "name": "details", - "type": "string" - }, - { - "internalType": "string", - "name": "imageURI", - "type": "string" - }, - { - "internalType": "bool", - "name": "isMutable", - "type": "bool" - }, - { - "internalType": "address", - "name": "wearer", - "type": "address" - }, - { - "components": [ - { - "internalType": "contract ISablierV2LockupLinear", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "internalType": "uint128", - "name": "totalAmount", - "type": "uint128" - }, - { - "internalType": "address", - "name": "asset", - "type": "address" - }, - { - "internalType": "bool", - "name": "cancelable", - "type": "bool" - }, - { - "internalType": "bool", - "name": "transferable", - "type": "bool" - }, - { - "components": [ - { - "internalType": "uint40", - "name": "start", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "cliff", - "type": "uint40" - }, - { - "internalType": "uint40", - "name": "end", - "type": "uint40" - } - ], - "internalType": "struct LockupLinear.Timestamps", - "name": "timestamps", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - } - ], - "internalType": "struct LockupLinear.Broker", - "name": "broker", - "type": "tuple" - } - ], - "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", - "name": "sablierParams", - "type": "tuple[]" - } - ], - "internalType": "struct DecentHats_0_1_0.Hat", - "name": "hat", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "topHatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "topHatAccount", - "type": "address" - }, - { - "internalType": "contract IERC6551Registry", - "name": "registry", - "type": "address" - }, - { - "internalType": "address", - "name": "hatsAccountImplementation", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "name": "createRoleHat", - "outputs": [ - { - "internalType": "uint256", - "name": "hatId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "accountAddress", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "getSalt", - "outputs": [ - { - "internalType": "bytes32", - "name": "salt", - "type": "bytes32" - } - ], - "stateMutability": "pure", - "type": "function" - } - ], - "transactionHash": "0xf40bd3ced4aeef501671b0cdb5b38737c085281f0b2147ac8e4aae18667fa1dd", - "receipt": { - "to": null, - "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", - "contractAddress": "0x0bEe0a447e6A5bEA8CAA0d8559A681EE16d6caCE", - "transactionIndex": 52, - "gasUsed": "1243979", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x348e807031247225bcd356c1719d5ef0ae8dec1556f477af9b569308deddf9f3", - "transactionHash": "0xf40bd3ced4aeef501671b0cdb5b38737c085281f0b2147ac8e4aae18667fa1dd", - "logs": [], - "blockNumber": 6943061, - "cumulativeGasUsed": "5696224", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 6, - "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", - "devdoc": { - "kind": "dev", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" - } - }, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": { - "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { - "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." - }, - "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { - "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." - } - }, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file diff --git a/deployments/sepolia/DecentSablierStreamManagement.json b/deployments/sepolia/DecentSablierStreamManagement.json deleted file mode 100644 index 3779fae4..00000000 --- a/deployments/sepolia/DecentSablierStreamManagement.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "address": "0x5874bf327bA5b78b2371b13eB414B66179591d34", - "abi": [ - { - "inputs": [], - "name": "NAME", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - } - ], - "name": "cancelStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "contract ISablierV2Lockup", - "name": "sablier", - "type": "address" - }, - { - "internalType": "address", - "name": "recipientHatAccount", - "type": "address" - }, - { - "internalType": "uint256", - "name": "streamId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "withdrawMaxFromStream", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", - "receipt": { - "to": null, - "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", - "contractAddress": "0x5874bf327bA5b78b2371b13eB414B66179591d34", - "transactionIndex": 72, - "gasUsed": "384441", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x2d90032ee5f61b968f6e38065b8dab930b88bb292edc0059448acc5e02903a4a", - "transactionHash": "0x5df751f83f960a27ef212bed1f54e8bf08a87056e74af2878fcfef8082d9eec3", - "logs": [], - "blockNumber": 6850325, - "cumulativeGasUsed": "8716271", - "status": 1, - "byzantium": true - }, - "args": [], - "numDeployments": 1, - "solcInputHash": "4511b61209438ca20d2458493e70bb24", - "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"}],\"name\":\"cancelStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ISablierV2Lockup\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipientHatAccount\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"streamId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawMaxFromStream\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentSablierStreamManagement.sol\":\"DecentSablierStreamManagement\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/interfaces/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/introspection/IERC165.sol\\\";\\n\",\"keccak256\":\"0xd04b0f06e0666f29cf7cccc82894de541e19bb30a765b107b1e40bb7fe5f7d7a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId,\\n bytes calldata data\\n ) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 tokenId\\n ) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the caller.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool _approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@prb/math/src/Common.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n// Common.sol\\n//\\n// Common mathematical functions used in both SD59x18 and UD60x18. Note that these global functions do not\\n// always operate with SD59x18 and UD60x18 numbers.\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CUSTOM ERRORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Thrown when the resultant value in {mulDiv} overflows uint256.\\nerror PRBMath_MulDiv_Overflow(uint256 x, uint256 y, uint256 denominator);\\n\\n/// @notice Thrown when the resultant value in {mulDiv18} overflows uint256.\\nerror PRBMath_MulDiv18_Overflow(uint256 x, uint256 y);\\n\\n/// @notice Thrown when one of the inputs passed to {mulDivSigned} is `type(int256).min`.\\nerror PRBMath_MulDivSigned_InputTooSmall();\\n\\n/// @notice Thrown when the resultant value in {mulDivSigned} overflows int256.\\nerror PRBMath_MulDivSigned_Overflow(int256 x, int256 y);\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CONSTANTS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @dev The maximum value a uint128 number can have.\\nuint128 constant MAX_UINT128 = type(uint128).max;\\n\\n/// @dev The maximum value a uint40 number can have.\\nuint40 constant MAX_UINT40 = type(uint40).max;\\n\\n/// @dev The unit number, which the decimal precision of the fixed-point types.\\nuint256 constant UNIT = 1e18;\\n\\n/// @dev The unit number inverted mod 2^256.\\nuint256 constant UNIT_INVERSE = 78156646155174841979727994598816262306175212592076161876661_508869554232690281;\\n\\n/// @dev The the largest power of two that divides the decimal value of `UNIT`. The logarithm of this value is the least significant\\n/// bit in the binary representation of `UNIT`.\\nuint256 constant UNIT_LPOTD = 262144;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n/// @dev Has to use 192.64-bit fixed-point numbers. See https://ethereum.stackexchange.com/a/96594/24693.\\n/// @param x The exponent as an unsigned 192.64-bit fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(uint256 x) pure returns (uint256 result) {\\n unchecked {\\n // Start from 0.5 in the 192.64-bit fixed-point format.\\n result = 0x800000000000000000000000000000000000000000000000;\\n\\n // The following logic multiplies the result by $\\\\sqrt{2^{-i}}$ when the bit at position i is 1. Key points:\\n //\\n // 1. Intermediate results will not overflow, as the starting point is 2^191 and all magic factors are under 2^65.\\n // 2. The rationale for organizing the if statements into groups of 8 is gas savings. If the result of performing\\n // a bitwise AND operation between x and any value in the array [0x80; 0x40; 0x20; 0x10; 0x08; 0x04; 0x02; 0x01] is 1,\\n // we know that `x & 0xFF` is also 1.\\n if (x & 0xFF00000000000000 > 0) {\\n if (x & 0x8000000000000000 > 0) {\\n result = (result * 0x16A09E667F3BCC909) >> 64;\\n }\\n if (x & 0x4000000000000000 > 0) {\\n result = (result * 0x1306FE0A31B7152DF) >> 64;\\n }\\n if (x & 0x2000000000000000 > 0) {\\n result = (result * 0x1172B83C7D517ADCE) >> 64;\\n }\\n if (x & 0x1000000000000000 > 0) {\\n result = (result * 0x10B5586CF9890F62A) >> 64;\\n }\\n if (x & 0x800000000000000 > 0) {\\n result = (result * 0x1059B0D31585743AE) >> 64;\\n }\\n if (x & 0x400000000000000 > 0) {\\n result = (result * 0x102C9A3E778060EE7) >> 64;\\n }\\n if (x & 0x200000000000000 > 0) {\\n result = (result * 0x10163DA9FB33356D8) >> 64;\\n }\\n if (x & 0x100000000000000 > 0) {\\n result = (result * 0x100B1AFA5ABCBED61) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000000000 > 0) {\\n if (x & 0x80000000000000 > 0) {\\n result = (result * 0x10058C86DA1C09EA2) >> 64;\\n }\\n if (x & 0x40000000000000 > 0) {\\n result = (result * 0x1002C605E2E8CEC50) >> 64;\\n }\\n if (x & 0x20000000000000 > 0) {\\n result = (result * 0x100162F3904051FA1) >> 64;\\n }\\n if (x & 0x10000000000000 > 0) {\\n result = (result * 0x1000B175EFFDC76BA) >> 64;\\n }\\n if (x & 0x8000000000000 > 0) {\\n result = (result * 0x100058BA01FB9F96D) >> 64;\\n }\\n if (x & 0x4000000000000 > 0) {\\n result = (result * 0x10002C5CC37DA9492) >> 64;\\n }\\n if (x & 0x2000000000000 > 0) {\\n result = (result * 0x1000162E525EE0547) >> 64;\\n }\\n if (x & 0x1000000000000 > 0) {\\n result = (result * 0x10000B17255775C04) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000000000 > 0) {\\n if (x & 0x800000000000 > 0) {\\n result = (result * 0x1000058B91B5BC9AE) >> 64;\\n }\\n if (x & 0x400000000000 > 0) {\\n result = (result * 0x100002C5C89D5EC6D) >> 64;\\n }\\n if (x & 0x200000000000 > 0) {\\n result = (result * 0x10000162E43F4F831) >> 64;\\n }\\n if (x & 0x100000000000 > 0) {\\n result = (result * 0x100000B1721BCFC9A) >> 64;\\n }\\n if (x & 0x80000000000 > 0) {\\n result = (result * 0x10000058B90CF1E6E) >> 64;\\n }\\n if (x & 0x40000000000 > 0) {\\n result = (result * 0x1000002C5C863B73F) >> 64;\\n }\\n if (x & 0x20000000000 > 0) {\\n result = (result * 0x100000162E430E5A2) >> 64;\\n }\\n if (x & 0x10000000000 > 0) {\\n result = (result * 0x1000000B172183551) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00000000 > 0) {\\n if (x & 0x8000000000 > 0) {\\n result = (result * 0x100000058B90C0B49) >> 64;\\n }\\n if (x & 0x4000000000 > 0) {\\n result = (result * 0x10000002C5C8601CC) >> 64;\\n }\\n if (x & 0x2000000000 > 0) {\\n result = (result * 0x1000000162E42FFF0) >> 64;\\n }\\n if (x & 0x1000000000 > 0) {\\n result = (result * 0x10000000B17217FBB) >> 64;\\n }\\n if (x & 0x800000000 > 0) {\\n result = (result * 0x1000000058B90BFCE) >> 64;\\n }\\n if (x & 0x400000000 > 0) {\\n result = (result * 0x100000002C5C85FE3) >> 64;\\n }\\n if (x & 0x200000000 > 0) {\\n result = (result * 0x10000000162E42FF1) >> 64;\\n }\\n if (x & 0x100000000 > 0) {\\n result = (result * 0x100000000B17217F8) >> 64;\\n }\\n }\\n\\n if (x & 0xFF000000 > 0) {\\n if (x & 0x80000000 > 0) {\\n result = (result * 0x10000000058B90BFC) >> 64;\\n }\\n if (x & 0x40000000 > 0) {\\n result = (result * 0x1000000002C5C85FE) >> 64;\\n }\\n if (x & 0x20000000 > 0) {\\n result = (result * 0x100000000162E42FF) >> 64;\\n }\\n if (x & 0x10000000 > 0) {\\n result = (result * 0x1000000000B17217F) >> 64;\\n }\\n if (x & 0x8000000 > 0) {\\n result = (result * 0x100000000058B90C0) >> 64;\\n }\\n if (x & 0x4000000 > 0) {\\n result = (result * 0x10000000002C5C860) >> 64;\\n }\\n if (x & 0x2000000 > 0) {\\n result = (result * 0x1000000000162E430) >> 64;\\n }\\n if (x & 0x1000000 > 0) {\\n result = (result * 0x10000000000B17218) >> 64;\\n }\\n }\\n\\n if (x & 0xFF0000 > 0) {\\n if (x & 0x800000 > 0) {\\n result = (result * 0x1000000000058B90C) >> 64;\\n }\\n if (x & 0x400000 > 0) {\\n result = (result * 0x100000000002C5C86) >> 64;\\n }\\n if (x & 0x200000 > 0) {\\n result = (result * 0x10000000000162E43) >> 64;\\n }\\n if (x & 0x100000 > 0) {\\n result = (result * 0x100000000000B1721) >> 64;\\n }\\n if (x & 0x80000 > 0) {\\n result = (result * 0x10000000000058B91) >> 64;\\n }\\n if (x & 0x40000 > 0) {\\n result = (result * 0x1000000000002C5C8) >> 64;\\n }\\n if (x & 0x20000 > 0) {\\n result = (result * 0x100000000000162E4) >> 64;\\n }\\n if (x & 0x10000 > 0) {\\n result = (result * 0x1000000000000B172) >> 64;\\n }\\n }\\n\\n if (x & 0xFF00 > 0) {\\n if (x & 0x8000 > 0) {\\n result = (result * 0x100000000000058B9) >> 64;\\n }\\n if (x & 0x4000 > 0) {\\n result = (result * 0x10000000000002C5D) >> 64;\\n }\\n if (x & 0x2000 > 0) {\\n result = (result * 0x1000000000000162E) >> 64;\\n }\\n if (x & 0x1000 > 0) {\\n result = (result * 0x10000000000000B17) >> 64;\\n }\\n if (x & 0x800 > 0) {\\n result = (result * 0x1000000000000058C) >> 64;\\n }\\n if (x & 0x400 > 0) {\\n result = (result * 0x100000000000002C6) >> 64;\\n }\\n if (x & 0x200 > 0) {\\n result = (result * 0x10000000000000163) >> 64;\\n }\\n if (x & 0x100 > 0) {\\n result = (result * 0x100000000000000B1) >> 64;\\n }\\n }\\n\\n if (x & 0xFF > 0) {\\n if (x & 0x80 > 0) {\\n result = (result * 0x10000000000000059) >> 64;\\n }\\n if (x & 0x40 > 0) {\\n result = (result * 0x1000000000000002C) >> 64;\\n }\\n if (x & 0x20 > 0) {\\n result = (result * 0x10000000000000016) >> 64;\\n }\\n if (x & 0x10 > 0) {\\n result = (result * 0x1000000000000000B) >> 64;\\n }\\n if (x & 0x8 > 0) {\\n result = (result * 0x10000000000000006) >> 64;\\n }\\n if (x & 0x4 > 0) {\\n result = (result * 0x10000000000000003) >> 64;\\n }\\n if (x & 0x2 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n if (x & 0x1 > 0) {\\n result = (result * 0x10000000000000001) >> 64;\\n }\\n }\\n\\n // In the code snippet below, two operations are executed simultaneously:\\n //\\n // 1. The result is multiplied by $(2^n + 1)$, where $2^n$ represents the integer part, and the additional 1\\n // accounts for the initial guess of 0.5. This is achieved by subtracting from 191 instead of 192.\\n // 2. The result is then converted to an unsigned 60.18-decimal fixed-point format.\\n //\\n // The underlying logic is based on the relationship $2^{191-ip} = 2^{ip} / 2^{191}$, where $ip$ denotes the,\\n // integer part, $2^n$.\\n result *= UNIT;\\n result >>= (191 - (x >> 64));\\n }\\n}\\n\\n/// @notice Finds the zero-based index of the first 1 in the binary representation of x.\\n///\\n/// @dev See the note on \\\"msb\\\" in this Wikipedia article: https://en.wikipedia.org/wiki/Find_first_set\\n///\\n/// Each step in this implementation is equivalent to this high-level code:\\n///\\n/// ```solidity\\n/// if (x >= 2 ** 128) {\\n/// x >>= 128;\\n/// result += 128;\\n/// }\\n/// ```\\n///\\n/// Where 128 is replaced with each respective power of two factor. See the full high-level implementation here:\\n/// https://gist.github.com/PaulRBerg/f932f8693f2733e30c4d479e8e980948\\n///\\n/// The Yul instructions used below are:\\n///\\n/// - \\\"gt\\\" is \\\"greater than\\\"\\n/// - \\\"or\\\" is the OR bitwise operator\\n/// - \\\"shl\\\" is \\\"shift left\\\"\\n/// - \\\"shr\\\" is \\\"shift right\\\"\\n///\\n/// @param x The uint256 number for which to find the index of the most significant bit.\\n/// @return result The index of the most significant bit as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction msb(uint256 x) pure returns (uint256 result) {\\n // 2^128\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^64\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^32\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(5, gt(x, 0xFFFFFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^16\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(4, gt(x, 0xFFFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^8\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(3, gt(x, 0xFF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^4\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(2, gt(x, 0xF))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^2\\n assembly (\\\"memory-safe\\\") {\\n let factor := shl(1, gt(x, 0x3))\\n x := shr(factor, x)\\n result := or(result, factor)\\n }\\n // 2^1\\n // No need to shift x any more.\\n assembly (\\\"memory-safe\\\") {\\n let factor := gt(x, 0x1)\\n result := or(result, factor)\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev Credits to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - The denominator must not be zero.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as a uint256.\\n/// @param y The multiplier as a uint256.\\n/// @param denominator The divisor as a uint256.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv(uint256 x, uint256 y, uint256 denominator) pure returns (uint256 result) {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / denominator;\\n }\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (prod1 >= denominator) {\\n revert PRBMath_MulDiv_Overflow(x, y, denominator);\\n }\\n\\n ////////////////////////////////////////////////////////////////////////////\\n // 512 by 256 division\\n ////////////////////////////////////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n // Compute remainder using the mulmod Yul instruction.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512-bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n unchecked {\\n // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow\\n // because the denominator cannot be zero at this point in the function execution. The result is always >= 1.\\n // For more detail, see https://cs.stackexchange.com/q/138556/92363.\\n uint256 lpotdod = denominator & (~denominator + 1);\\n uint256 flippedLpotdod;\\n\\n assembly (\\\"memory-safe\\\") {\\n // Factor powers of two out of denominator.\\n denominator := div(denominator, lpotdod)\\n\\n // Divide [prod1 prod0] by lpotdod.\\n prod0 := div(prod0, lpotdod)\\n\\n // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one.\\n // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits.\\n // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693\\n flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * flippedLpotdod;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f71e18 with 512-bit precision.\\n///\\n/// @dev A variant of {mulDiv} with constant folding, i.e. in which the denominator is hard coded to 1e18.\\n///\\n/// Notes:\\n/// - The body is purposely left uncommented; to understand how this works, see the documentation in {mulDiv}.\\n/// - The result is rounded toward zero.\\n/// - We take as an axiom that the result cannot be `MAX_UINT256` when x and y solve the following system of equations:\\n///\\n/// $$\\n/// \\\\begin{cases}\\n/// x * y = MAX\\\\_UINT256 * UNIT \\\\\\\\\\n/// (x * y) \\\\% UNIT \\\\geq \\\\frac{UNIT}{2}\\n/// \\\\end{cases}\\n/// $$\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - The result must fit in uint256.\\n///\\n/// @param x The multiplicand as an unsigned 60.18-decimal fixed-point number.\\n/// @param y The multiplier as an unsigned 60.18-decimal fixed-point number.\\n/// @return result The result as an unsigned 60.18-decimal fixed-point number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDiv18(uint256 x, uint256 y) pure returns (uint256 result) {\\n uint256 prod0;\\n uint256 prod1;\\n assembly (\\\"memory-safe\\\") {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n if (prod1 == 0) {\\n unchecked {\\n return prod0 / UNIT;\\n }\\n }\\n\\n if (prod1 >= UNIT) {\\n revert PRBMath_MulDiv18_Overflow(x, y);\\n }\\n\\n uint256 remainder;\\n assembly (\\\"memory-safe\\\") {\\n remainder := mulmod(x, y, UNIT)\\n result :=\\n mul(\\n or(\\n div(sub(prod0, remainder), UNIT_LPOTD),\\n mul(sub(prod1, gt(remainder, prod0)), add(div(sub(0, UNIT_LPOTD), UNIT_LPOTD), 1))\\n ),\\n UNIT_INVERSE\\n )\\n }\\n}\\n\\n/// @notice Calculates x*y\\u00f7denominator with 512-bit precision.\\n///\\n/// @dev This is an extension of {mulDiv} for signed numbers, which works by computing the signs and the absolute values separately.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {mulDiv}.\\n/// - None of the inputs can be `type(int256).min`.\\n/// - The result must fit in int256.\\n///\\n/// @param x The multiplicand as an int256.\\n/// @param y The multiplier as an int256.\\n/// @param denominator The divisor as an int256.\\n/// @return result The result as an int256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mulDivSigned(int256 x, int256 y, int256 denominator) pure returns (int256 result) {\\n if (x == type(int256).min || y == type(int256).min || denominator == type(int256).min) {\\n revert PRBMath_MulDivSigned_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x, y and the denominator.\\n uint256 xAbs;\\n uint256 yAbs;\\n uint256 dAbs;\\n unchecked {\\n xAbs = x < 0 ? uint256(-x) : uint256(x);\\n yAbs = y < 0 ? uint256(-y) : uint256(y);\\n dAbs = denominator < 0 ? uint256(-denominator) : uint256(denominator);\\n }\\n\\n // Compute the absolute value of x*y\\u00f7denominator. The result must fit in int256.\\n uint256 resultAbs = mulDiv(xAbs, yAbs, dAbs);\\n if (resultAbs > uint256(type(int256).max)) {\\n revert PRBMath_MulDivSigned_Overflow(x, y);\\n }\\n\\n // Get the signs of x, y and the denominator.\\n uint256 sx;\\n uint256 sy;\\n uint256 sd;\\n assembly (\\\"memory-safe\\\") {\\n // \\\"sgt\\\" is the \\\"signed greater than\\\" assembly instruction and \\\"sub(0,1)\\\" is -1 in two's complement.\\n sx := sgt(x, sub(0, 1))\\n sy := sgt(y, sub(0, 1))\\n sd := sgt(denominator, sub(0, 1))\\n }\\n\\n // XOR over sx, sy and sd. What this does is to check whether there are 1 or 3 negative signs in the inputs.\\n // If there are, the result should be negative. Otherwise, it should be positive.\\n unchecked {\\n result = sx ^ sy ^ sd == 0 ? -int256(resultAbs) : int256(resultAbs);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - If x is not a perfect square, the result is rounded down.\\n/// - Credits to OpenZeppelin for the explanations in comments below.\\n///\\n/// @param x The uint256 number for which to calculate the square root.\\n/// @return result The result as a uint256.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(uint256 x) pure returns (uint256 result) {\\n if (x == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we calculate the biggest power of 2 which is smaller than the square root of x.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of x is a power of 2 such that we have:\\n //\\n // $$\\n // msb(x) <= x <= 2*msb(x)$\\n // $$\\n //\\n // We write $msb(x)$ as $2^k$, and we get:\\n //\\n // $$\\n // k = log_2(x)\\n // $$\\n //\\n // Thus, we can write the initial inequality as:\\n //\\n // $$\\n // 2^{log_2(x)} <= x <= 2*2^{log_2(x)+1} \\\\\\\\\\n // sqrt(2^k) <= sqrt(x) < sqrt(2^{k+1}) \\\\\\\\\\n // 2^{k/2} <= sqrt(x) < 2^{(k+1)/2} <= 2^{(k/2)+1}\\n // $$\\n //\\n // Consequently, $2^{log_2(x) /2} is a good first approximation of sqrt(x) with at least one correct bit.\\n uint256 xAux = uint256(x);\\n result = 1;\\n if (xAux >= 2 ** 128) {\\n xAux >>= 128;\\n result <<= 64;\\n }\\n if (xAux >= 2 ** 64) {\\n xAux >>= 64;\\n result <<= 32;\\n }\\n if (xAux >= 2 ** 32) {\\n xAux >>= 32;\\n result <<= 16;\\n }\\n if (xAux >= 2 ** 16) {\\n xAux >>= 16;\\n result <<= 8;\\n }\\n if (xAux >= 2 ** 8) {\\n xAux >>= 8;\\n result <<= 4;\\n }\\n if (xAux >= 2 ** 4) {\\n xAux >>= 4;\\n result <<= 2;\\n }\\n if (xAux >= 2 ** 2) {\\n result <<= 1;\\n }\\n\\n // At this point, `result` is an estimation with at least one bit of precision. We know the true value has at\\n // most 128 bits, since it is the square root of a uint256. Newton's method converges quadratically (precision\\n // doubles at every iteration). We thus need at most 7 iteration to turn our partial result with one bit of\\n // precision into the expected uint128 result.\\n unchecked {\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n result = (result + x / result) >> 1;\\n\\n // If x is not a perfect square, round the result toward zero.\\n uint256 roundedResult = x / result;\\n if (result >= roundedResult) {\\n result = roundedResult;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaa374e2c26cc93e8c22a6953804ee05f811597ef5fa82f76824378b22944778b\",\"license\":\"MIT\"},\"@prb/math/src/UD2x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud2x18/Casting.sol\\\";\\nimport \\\"./ud2x18/Constants.sol\\\";\\nimport \\\"./ud2x18/Errors.sol\\\";\\nimport \\\"./ud2x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xfb624e24cd8bb790fa08e7827819de85504a86e20e961fa4ad126c65b6d90641\",\"license\":\"MIT\"},\"@prb/math/src/UD60x18.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\n/*\\n\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u255a\\u2550\\u2550\\u2588\\u2588\\u2554\\u2550\\u2550\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2588\\u2588\\u2588\\u2588\\u2557\\u255a\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551 \\u255a\\u2588\\u2588\\u2588\\u2554\\u255d \\u255a\\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2554\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n*/\\n\\nimport \\\"./ud60x18/Casting.sol\\\";\\nimport \\\"./ud60x18/Constants.sol\\\";\\nimport \\\"./ud60x18/Conversions.sol\\\";\\nimport \\\"./ud60x18/Errors.sol\\\";\\nimport \\\"./ud60x18/Helpers.sol\\\";\\nimport \\\"./ud60x18/Math.sol\\\";\\nimport \\\"./ud60x18/ValueType.sol\\\";\\n\",\"keccak256\":\"0xb98c6f74275914d279e8af6c502c2b1f50d5f6e1ed418d3b0153f5a193206c48\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD1x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of SD1x18 is a subset of SD59x18.\\nfunction intoSD59x18(SD1x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(SD1x18.unwrap(x)));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD2x18.\\n/// - x must be positive.\\nfunction intoUD2x18(SD1x18 x) pure returns (UD2x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD2x18_Underflow(x);\\n }\\n result = UD2x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD1x18 x) pure returns (UD60x18 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD1x18 x) pure returns (uint256 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint256_Underflow(x);\\n }\\n result = uint256(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint128(SD1x18 x) pure returns (uint128 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint128_Underflow(x);\\n }\\n result = uint128(uint64(xInt));\\n}\\n\\n/// @notice Casts an SD1x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD1x18 x) pure returns (uint40 result) {\\n int64 xInt = SD1x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Underflow(x);\\n }\\n if (xInt > int64(uint64(Common.MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD1x18_ToUint40_Overflow(x);\\n }\\n result = uint40(uint64(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd1x18(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD1x18 number into int64.\\nfunction unwrap(SD1x18 x) pure returns (int64 result) {\\n result = SD1x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int64 number into SD1x18.\\nfunction wrap(int64 x) pure returns (SD1x18 result) {\\n result = SD1x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9e49e2b37c1bb845861740805edaaef3fe951a7b96eef16ce84fbf76e8278670\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as an SD1x18 number.\\nSD1x18 constant E = SD1x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMAX_SD1x18 = 9_223372036854775807;\\nSD1x18 constant MAX_SD1x18 = SD1x18.wrap(uMAX_SD1x18);\\n\\n/// @dev The maximum value an SD1x18 number can have.\\nint64 constant uMIN_SD1x18 = -9_223372036854775808;\\nSD1x18 constant MIN_SD1x18 = SD1x18.wrap(uMIN_SD1x18);\\n\\n/// @dev PI as an SD1x18 number.\\nSD1x18 constant PI = SD1x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD1x18.\\nSD1x18 constant UNIT = SD1x18.wrap(1e18);\\nint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x6496165b80552785a4b65a239b96e2a5fedf62fe54f002eeed72d75e566d7585\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD1x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD1x18_ToUD2x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD1x18_ToUD60x18_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint128.\\nerror PRBMath_SD1x18_ToUint128_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint256.\\nerror PRBMath_SD1x18_ToUint256_Underflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Overflow(SD1x18 x);\\n\\n/// @notice Thrown when trying to cast a SD1x18 number that doesn't fit in uint40.\\nerror PRBMath_SD1x18_ToUint40_Underflow(SD1x18 x);\\n\",\"keccak256\":\"0x836cb42ba619ca369fd4765bc47fefc3c3621369c5861882af14660aca5057ee\",\"license\":\"MIT\"},\"@prb/math/src/sd1x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int64. This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype SD1x18 is int64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD59x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD1x18 global;\\n\",\"keccak256\":\"0x2f86f1aa9fca42f40808b51a879b406ac51817647bdb9642f8a79dd8fdb754a7\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18, uMIN_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts an SD59x18 number into int256.\\n/// @dev This is basically a functional alias for {unwrap}.\\nfunction intoInt256(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Casts an SD59x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be greater than or equal to `uMIN_SD1x18`.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(SD59x18 x) pure returns (SD1x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < uMIN_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Underflow(x);\\n }\\n if (xInt > uMAX_SD1x18) {\\n revert CastingErrors.PRBMath_SD59x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(SD59x18 x) pure returns (UD2x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Underflow(x);\\n }\\n if (xInt > int256(uint256(uMAX_UD2x18))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(uint256(xInt)));\\n}\\n\\n/// @notice Casts an SD59x18 number into UD60x18.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUD60x18(SD59x18 x) pure returns (UD60x18 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUD60x18_Underflow(x);\\n }\\n result = UD60x18.wrap(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint256.\\n/// @dev Requirements:\\n/// - x must be positive.\\nfunction intoUint256(SD59x18 x) pure returns (uint256 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint256_Underflow(x);\\n }\\n result = uint256(xInt);\\n}\\n\\n/// @notice Casts an SD59x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `uMAX_UINT128`.\\nfunction intoUint128(SD59x18 x) pure returns (uint128 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT128))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(uint256(xInt));\\n}\\n\\n/// @notice Casts an SD59x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be positive.\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(SD59x18 x) pure returns (uint40 result) {\\n int256 xInt = SD59x18.unwrap(x);\\n if (xInt < 0) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Underflow(x);\\n }\\n if (xInt > int256(uint256(MAX_UINT40))) {\\n revert CastingErrors.PRBMath_SD59x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(uint256(xInt));\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction sd59x18(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\\n/// @notice Unwraps an SD59x18 number into int256.\\nfunction unwrap(SD59x18 x) pure returns (int256 result) {\\n result = SD59x18.unwrap(x);\\n}\\n\\n/// @notice Wraps an int256 number into SD59x18.\\nfunction wrap(int256 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x3b21b60ec2998c3ae32f647412da51d3683b3f183a807198cc8d157499484f99\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as an SD59x18 number.\\nSD59x18 constant E = SD59x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nSD59x18 constant EXP_MAX_INPUT = SD59x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp}.\\nint256 constant uEXP_MIN_THRESHOLD = -41_446531673892822322;\\nSD59x18 constant EXP_MIN_THRESHOLD = SD59x18.wrap(uEXP_MIN_THRESHOLD);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nSD59x18 constant EXP2_MAX_INPUT = SD59x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Any value less than this returns 0 in {exp2}.\\nint256 constant uEXP2_MIN_THRESHOLD = -59_794705707972522261;\\nSD59x18 constant EXP2_MIN_THRESHOLD = SD59x18.wrap(uEXP2_MIN_THRESHOLD);\\n\\n/// @dev Half the UNIT number.\\nint256 constant uHALF_UNIT = 0.5e18;\\nSD59x18 constant HALF_UNIT = SD59x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as an SD59x18 number.\\nint256 constant uLOG2_10 = 3_321928094887362347;\\nSD59x18 constant LOG2_10 = SD59x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as an SD59x18 number.\\nint256 constant uLOG2_E = 1_442695040888963407;\\nSD59x18 constant LOG2_E = SD59x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value an SD59x18 number can have.\\nint256 constant uMAX_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_792003956564819967;\\nSD59x18 constant MAX_SD59x18 = SD59x18.wrap(uMAX_SD59x18);\\n\\n/// @dev The maximum whole value an SD59x18 number can have.\\nint256 constant uMAX_WHOLE_SD59x18 = 57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MAX_WHOLE_SD59x18 = SD59x18.wrap(uMAX_WHOLE_SD59x18);\\n\\n/// @dev The minimum value an SD59x18 number can have.\\nint256 constant uMIN_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_792003956564819968;\\nSD59x18 constant MIN_SD59x18 = SD59x18.wrap(uMIN_SD59x18);\\n\\n/// @dev The minimum whole value an SD59x18 number can have.\\nint256 constant uMIN_WHOLE_SD59x18 = -57896044618658097711785492504343953926634992332820282019728_000000000000000000;\\nSD59x18 constant MIN_WHOLE_SD59x18 = SD59x18.wrap(uMIN_WHOLE_SD59x18);\\n\\n/// @dev PI as an SD59x18 number.\\nSD59x18 constant PI = SD59x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of SD59x18.\\nint256 constant uUNIT = 1e18;\\nSD59x18 constant UNIT = SD59x18.wrap(1e18);\\n\\n/// @dev The unit number squared.\\nint256 constant uUNIT_SQUARED = 1e36;\\nSD59x18 constant UNIT_SQUARED = SD59x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as an SD59x18 number.\\nSD59x18 constant ZERO = SD59x18.wrap(0);\\n\",\"keccak256\":\"0x9bcb8dd6b3e886d140ad1c32747a4f6d29a492529ceb835be878ae837aa6cc3a\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when taking the absolute value of `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Abs_MinSD59x18();\\n\\n/// @notice Thrown when ceiling a number overflows SD59x18.\\nerror PRBMath_SD59x18_Ceil_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Overflow(int256 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format underflows SD59x18.\\nerror PRBMath_SD59x18_Convert_Underflow(int256 x);\\n\\n/// @notice Thrown when dividing two numbers and one of them is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Div_InputTooSmall();\\n\\n/// @notice Thrown when dividing two numbers and one of the intermediary unsigned results overflows SD59x18.\\nerror PRBMath_SD59x18_Div_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_SD59x18_Exp_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_SD59x18_Exp2_InputTooBig(SD59x18 x);\\n\\n/// @notice Thrown when flooring a number underflows SD59x18.\\nerror PRBMath_SD59x18_Floor_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and their product is negative.\\nerror PRBMath_SD59x18_Gm_NegativeProduct(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows SD59x18.\\nerror PRBMath_SD59x18_Gm_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_SD59x18_IntoSD1x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_SD59x18_IntoUD2x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD60x18.\\nerror PRBMath_SD59x18_IntoUD60x18_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_SD59x18_IntoUint128_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint256.\\nerror PRBMath_SD59x18_IntoUint256_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Overflow(SD59x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_SD59x18_IntoUint40_Underflow(SD59x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than or equal to zero.\\nerror PRBMath_SD59x18_Log_InputTooSmall(SD59x18 x);\\n\\n/// @notice Thrown when multiplying two numbers and one of the inputs is `MIN_SD59x18`.\\nerror PRBMath_SD59x18_Mul_InputTooSmall();\\n\\n/// @notice Thrown when multiplying two numbers and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Mul_Overflow(SD59x18 x, SD59x18 y);\\n\\n/// @notice Thrown when raising a number to a power and the intermediary absolute result overflows SD59x18.\\nerror PRBMath_SD59x18_Powu_Overflow(SD59x18 x, uint256 y);\\n\\n/// @notice Thrown when taking the square root of a negative number.\\nerror PRBMath_SD59x18_Sqrt_NegativeInput(SD59x18 x);\\n\\n/// @notice Thrown when the calculating the square root overflows SD59x18.\\nerror PRBMath_SD59x18_Sqrt_Overflow(SD59x18 x);\\n\",\"keccak256\":\"0xa6d00fe5efa215ac0df25c896e3da99a12fb61e799644b2ec32da947313d3db4\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the SD59x18 type.\\nfunction add(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and(SD59x18 x, int256 bits) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the SD59x18 type.\\nfunction and2(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n return wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal (=) operation in the SD59x18 type.\\nfunction eq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the SD59x18 type.\\nfunction gt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the SD59x18 type.\\nfunction gte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the SD59x18 type.\\nfunction isZero(SD59x18 x) pure returns (bool result) {\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the SD59x18 type.\\nfunction lshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the SD59x18 type.\\nfunction lt(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the SD59x18 type.\\nfunction lte(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the unchecked modulo operation (%) in the SD59x18 type.\\nfunction mod(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the SD59x18 type.\\nfunction neq(SD59x18 x, SD59x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the SD59x18 type.\\nfunction not(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the SD59x18 type.\\nfunction or(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the SD59x18 type.\\nfunction rshift(SD59x18 x, uint256 bits) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the SD59x18 type.\\nfunction sub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the checked unary minus operation (-) in the SD59x18 type.\\nfunction unary(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(-x.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the SD59x18 type.\\nfunction uncheckedAdd(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the SD59x18 type.\\nfunction uncheckedSub(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked unary minus operation (-) in the SD59x18 type.\\nfunction uncheckedUnary(SD59x18 x) pure returns (SD59x18 result) {\\n unchecked {\\n result = wrap(-x.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the SD59x18 type.\\nfunction xor(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0x208570f1657cf730cb6c3d81aa14030e0d45cf906cdedea5059369d7df4bb716\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uEXP_MIN_THRESHOLD,\\n uEXP2_MIN_THRESHOLD,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_SD59x18,\\n uMAX_WHOLE_SD59x18,\\n uMIN_SD59x18,\\n uMIN_WHOLE_SD59x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { wrap } from \\\"./Helpers.sol\\\";\\nimport { SD59x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Calculates the absolute value of x.\\n///\\n/// @dev Requirements:\\n/// - x must be greater than `MIN_SD59x18`.\\n///\\n/// @param x The SD59x18 number for which to calculate the absolute value.\\n/// @param result The absolute value of x as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction abs(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Abs_MinSD59x18();\\n }\\n result = xInt < 0 ? wrap(-xInt) : x;\\n}\\n\\n/// @notice Calculates the arithmetic average of x and y.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The arithmetic average as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n unchecked {\\n // This operation is equivalent to `x / 2 + y / 2`, and it can never overflow.\\n int256 sum = (xInt >> 1) + (yInt >> 1);\\n\\n if (sum < 0) {\\n // If at least one of x and y is odd, add 1 to the result, because shifting negative numbers to the right\\n // rounds toward negative infinity. The right part is equivalent to `sum + (x % 2 == 1 || y % 2 == 1)`.\\n assembly (\\\"memory-safe\\\") {\\n result := add(sum, and(or(xInt, yInt), 1))\\n }\\n } else {\\n // Add 1 if both x and y are odd to account for the double 0.5 remainder truncated after shifting.\\n result = wrap(sum + (xInt & yInt & 1));\\n }\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt > uMAX_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Ceil_Overflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt > 0) {\\n resultInt += uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Divides two SD59x18 numbers, returning a new SD59x18 number.\\n///\\n/// @dev This is an extension of {Common.mulDiv} for signed numbers, which works by computing the signs and the absolute\\n/// values separately.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The denominator must not be zero.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The numerator as an SD59x18 number.\\n/// @param y The denominator as an SD59x18 number.\\n/// @param result The quotient as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Div_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*UNIT\\u00f7y). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv(xAbs, uint256(uUNIT), yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Div_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}.\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n\\n // Any input less than the threshold returns zero.\\n // This check also prevents an overflow for very small numbers.\\n if (xInt < uEXP_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xInt > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n int256 doubleUnitProduct = xInt * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method using the following formula:\\n///\\n/// $$\\n/// 2^{-x} = \\\\frac{1}{2^x}\\n/// $$\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693.\\n///\\n/// Notes:\\n/// - If x is less than -59_794705707972522261, the result is zero.\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The exponent as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n // The inverse of any number less than the threshold is truncated to zero.\\n if (xInt < uEXP2_MIN_THRESHOLD) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Inline the fixed-point inversion to save gas.\\n result = wrap(uUNIT_SQUARED / exp2(wrap(-xInt)).unwrap());\\n }\\n } else {\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xInt > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_SD59x18_Exp2_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = uint256((xInt << 64) / uUNIT);\\n\\n // It is safe to cast the result to int256 due to the checks above.\\n result = wrap(int256(Common.exp2(x_192x64)));\\n }\\n }\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n///\\n/// @dev Optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be greater than or equal to `MIN_WHOLE_SD59x18`.\\n///\\n/// @param x The SD59x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < uMIN_WHOLE_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Floor_Underflow(x);\\n }\\n\\n int256 remainder = xInt % uUNIT;\\n if (remainder == 0) {\\n result = x;\\n } else {\\n unchecked {\\n // Solidity uses C fmod style, which returns a modulus with the same sign as x.\\n int256 resultInt = xInt - remainder;\\n if (xInt < 0) {\\n resultInt -= uUNIT;\\n }\\n result = wrap(resultInt);\\n }\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x for positive numbers and the part of the number to the right.\\n/// of the radix point for negative numbers.\\n/// @dev Based on the odd function definition. https://en.wikipedia.org/wiki/Fractional_part\\n/// @param x The SD59x18 number to get the fractional part of.\\n/// @param result The fractional part of x as an SD59x18 number.\\nfunction frac(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(x.unwrap() % uUNIT);\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x * y must fit in SD59x18.\\n/// - x * y must not be negative, since complex numbers are not supported.\\n///\\n/// @param x The first operand as an SD59x18 number.\\n/// @param y The second operand as an SD59x18 number.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == 0 || yInt == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Equivalent to `xy / x != y`. Checking for overflow this way is faster than letting Solidity do it.\\n int256 xyInt = xInt * yInt;\\n if (xyInt / xInt != yInt) {\\n revert Errors.PRBMath_SD59x18_Gm_Overflow(x, y);\\n }\\n\\n // The product must not be negative, since complex numbers are not supported.\\n if (xyInt < 0) {\\n revert Errors.PRBMath_SD59x18_Gm_NegativeProduct(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n uint256 resultUint = Common.sqrt(uint256(xyInt));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the inverse.\\n/// @return result The inverse as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(SD59x18 x) pure returns (SD59x18 result) {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(SD59x18 x) pure returns (SD59x18 result) {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~195_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The SD59x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this block is the standard multiplication operation, not {SD59x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n default { result := uMAX_SD59x18 }\\n }\\n\\n if (result.unwrap() == uMAX_SD59x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation.\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The SD59x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt <= 0) {\\n revert Errors.PRBMath_SD59x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n int256 sign;\\n if (xInt >= uUNIT) {\\n sign = 1;\\n } else {\\n sign = -1;\\n // Inline the fixed-point inversion to save gas.\\n xInt = uUNIT_SQUARED / xInt;\\n }\\n\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(uint256(xInt / uUNIT));\\n\\n // This is the integer part of the logarithm as an SD59x18 number. The operation can't overflow\\n // because n is at most 255, `UNIT` is 1e18, and the sign is either 1 or -1.\\n int256 resultInt = int256(n) * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n int256 y = xInt >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultInt * sign);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n int256 DOUBLE_UNIT = 2e18;\\n for (int256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultInt = resultInt + delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n resultInt *= sign;\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Multiplies two SD59x18 numbers together, returning a new SD59x18 number.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv18}.\\n/// - None of the inputs can be `MIN_SD59x18`.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The multiplicand as an SD59x18 number.\\n/// @param y The multiplier as an SD59x18 number.\\n/// @return result The product as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n if (xInt == uMIN_SD59x18 || yInt == uMIN_SD59x18) {\\n revert Errors.PRBMath_SD59x18_Mul_InputTooSmall();\\n }\\n\\n // Get hold of the absolute values of x and y.\\n uint256 xAbs;\\n uint256 yAbs;\\n unchecked {\\n xAbs = xInt < 0 ? uint256(-xInt) : uint256(xInt);\\n yAbs = yInt < 0 ? uint256(-yInt) : uint256(yInt);\\n }\\n\\n // Compute the absolute value (x*y\\u00f7UNIT). The resulting value must fit in SD59x18.\\n uint256 resultAbs = Common.mulDiv18(xAbs, yAbs);\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Mul_Overflow(x, y);\\n }\\n\\n // Check if x and y have the same sign using two's complement representation. The left-most bit represents the sign (1 for\\n // negative, 0 for positive or zero).\\n bool sameSign = (xInt ^ yInt) > -1;\\n\\n // If the inputs have the same sign, the result should be positive. Otherwise, it should be negative.\\n unchecked {\\n result = wrap(sameSign ? int256(resultAbs) : -int256(resultAbs));\\n }\\n}\\n\\n/// @notice Raises x to the power of y using the following formula:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {exp2}, {log2}, and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y Exponent to raise x to, as an SD59x18 number\\n/// @return result x raised to power y, as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(SD59x18 x, SD59x18 y) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n int256 yInt = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xInt == 0) {\\n return yInt == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xInt == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yInt == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yInt == uUNIT) {\\n return x;\\n }\\n\\n // Calculate the result using the formula.\\n result = exp2(mul(log2(x), y));\\n}\\n\\n/// @notice Raises x (an SD59x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {abs} and {Common.mulDiv18}.\\n/// - The result must fit in SD59x18.\\n///\\n/// @param x The base as an SD59x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(SD59x18 x, uint256 y) pure returns (SD59x18 result) {\\n uint256 xAbs = uint256(abs(x).unwrap());\\n\\n // Calculate the first iteration of the loop in advance.\\n uint256 resultAbs = y & 1 > 0 ? xAbs : uint256(uUNIT);\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n uint256 yAux = y;\\n for (yAux >>= 1; yAux > 0; yAux >>= 1) {\\n xAbs = Common.mulDiv18(xAbs, xAbs);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (yAux & 1 > 0) {\\n resultAbs = Common.mulDiv18(resultAbs, xAbs);\\n }\\n }\\n\\n // The result must fit in SD59x18.\\n if (resultAbs > uint256(uMAX_SD59x18)) {\\n revert Errors.PRBMath_SD59x18_Powu_Overflow(x, y);\\n }\\n\\n unchecked {\\n // Is the base negative and the exponent odd? If yes, the result should be negative.\\n int256 resultInt = int256(resultAbs);\\n bool isNegative = x.unwrap() < 0 && y & 1 == 1;\\n if (isNegative) {\\n resultInt = -resultInt;\\n }\\n result = wrap(resultInt);\\n }\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - Only the positive root is returned.\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x cannot be negative, since complex numbers are not supported.\\n/// - x must be less than `MAX_SD59x18 / UNIT`.\\n///\\n/// @param x The SD59x18 number for which to calculate the square root.\\n/// @return result The result as an SD59x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(SD59x18 x) pure returns (SD59x18 result) {\\n int256 xInt = x.unwrap();\\n if (xInt < 0) {\\n revert Errors.PRBMath_SD59x18_Sqrt_NegativeInput(x);\\n }\\n if (xInt > uMAX_SD59x18 / uUNIT) {\\n revert Errors.PRBMath_SD59x18_Sqrt_Overflow(x);\\n }\\n\\n unchecked {\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two SD59x18 numbers.\\n // In this case, the two numbers are both the square root.\\n uint256 resultUint = Common.sqrt(uint256(xInt * uUNIT));\\n result = wrap(int256(resultUint));\\n }\\n}\\n\",\"keccak256\":\"0xa074831139fc89ca0e5a36086b30eb50896bb6770cd5823461b1f2769017d2f0\",\"license\":\"MIT\"},\"@prb/math/src/sd59x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The signed 59.18-decimal fixed-point number representation, which can have up to 59 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type int256.\\ntype SD59x18 is int256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoInt256,\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Math.abs,\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.log10,\\n Math.log2,\\n Math.ln,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.uncheckedUnary,\\n Helpers.xor\\n} for SD59x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the SD59x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.or as |,\\n Helpers.sub as -,\\n Helpers.unary as -,\\n Helpers.xor as ^\\n} for SD59x18 global;\\n\",\"keccak256\":\"0xe03112d145dcd5863aff24e5f381debaae29d446acd5666f3d640e3d9af738d7\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"../ud60x18/ValueType.sol\\\";\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD2x18 number into SD1x18.\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD2x18 x) pure returns (SD1x18 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(uMAX_SD1x18)) {\\n revert Errors.PRBMath_UD2x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(xUint));\\n}\\n\\n/// @notice Casts a UD2x18 number into SD59x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of SD59x18.\\nfunction intoSD59x18(UD2x18 x) pure returns (SD59x18 result) {\\n result = SD59x18.wrap(int256(uint256(UD2x18.unwrap(x))));\\n}\\n\\n/// @notice Casts a UD2x18 number into UD60x18.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of UD60x18.\\nfunction intoUD60x18(UD2x18 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint128.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint128.\\nfunction intoUint128(UD2x18 x) pure returns (uint128 result) {\\n result = uint128(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint256.\\n/// @dev There is no overflow check because the domain of UD2x18 is a subset of uint256.\\nfunction intoUint256(UD2x18 x) pure returns (uint256 result) {\\n result = uint256(UD2x18.unwrap(x));\\n}\\n\\n/// @notice Casts a UD2x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD2x18 x) pure returns (uint40 result) {\\n uint64 xUint = UD2x18.unwrap(x);\\n if (xUint > uint64(Common.MAX_UINT40)) {\\n revert Errors.PRBMath_UD2x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud2x18(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\\n/// @notice Unwrap a UD2x18 number into uint64.\\nfunction unwrap(UD2x18 x) pure returns (uint64 result) {\\n result = UD2x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint64 number into UD2x18.\\nfunction wrap(uint64 x) pure returns (UD2x18 result) {\\n result = UD2x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x9b1a35d432ef951a415fae8098b3c609a99b630a3d5464b3c8e1efa8893eea07\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @dev Euler's number as a UD2x18 number.\\nUD2x18 constant E = UD2x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum value a UD2x18 number can have.\\nuint64 constant uMAX_UD2x18 = 18_446744073709551615;\\nUD2x18 constant MAX_UD2x18 = UD2x18.wrap(uMAX_UD2x18);\\n\\n/// @dev PI as a UD2x18 number.\\nUD2x18 constant PI = UD2x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD2x18.\\nUD2x18 constant UNIT = UD2x18.wrap(1e18);\\nuint64 constant uUNIT = 1e18;\\n\",\"keccak256\":\"0x29b0e050c865899e1fb9022b460a7829cdee248c44c4299f068ba80695eec3fc\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD2x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD2x18_IntoSD1x18_Overflow(UD2x18 x);\\n\\n/// @notice Thrown when trying to cast a UD2x18 number that doesn't fit in uint40.\\nerror PRBMath_UD2x18_IntoUint40_Overflow(UD2x18 x);\\n\",\"keccak256\":\"0xdf1e22f0b4c8032bcc8b7f63fe3984e1387f3dc7b2e9ab381822249f75376d33\",\"license\":\"MIT\"},\"@prb/math/src/ud2x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\n\\n/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity\\n/// type uint64. This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract\\n/// storage.\\ntype UD2x18 is uint64;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoSD59x18,\\n Casting.intoUD60x18,\\n Casting.intoUint256,\\n Casting.intoUint128,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD2x18 global;\\n\",\"keccak256\":\"0x2802edc9869db116a0b5c490cc5f8554742f747183fa30ac5e9c80bb967e61a1\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Casting.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Errors.sol\\\" as CastingErrors;\\nimport { MAX_UINT128, MAX_UINT40 } from \\\"../Common.sol\\\";\\nimport { uMAX_SD1x18 } from \\\"../sd1x18/Constants.sol\\\";\\nimport { SD1x18 } from \\\"../sd1x18/ValueType.sol\\\";\\nimport { uMAX_SD59x18 } from \\\"../sd59x18/Constants.sol\\\";\\nimport { SD59x18 } from \\\"../sd59x18/ValueType.sol\\\";\\nimport { uMAX_UD2x18 } from \\\"../ud2x18/Constants.sol\\\";\\nimport { UD2x18 } from \\\"../ud2x18/ValueType.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Casts a UD60x18 number into SD1x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD1x18`.\\nfunction intoSD1x18(UD60x18 x) pure returns (SD1x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(int256(uMAX_SD1x18))) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD1x18_Overflow(x);\\n }\\n result = SD1x18.wrap(int64(uint64(xUint)));\\n}\\n\\n/// @notice Casts a UD60x18 number into UD2x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_UD2x18`.\\nfunction intoUD2x18(UD60x18 x) pure returns (UD2x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uMAX_UD2x18) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUD2x18_Overflow(x);\\n }\\n result = UD2x18.wrap(uint64(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into SD59x18.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `uMAX_SD59x18`.\\nfunction intoSD59x18(UD60x18 x) pure returns (SD59x18 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > uint256(uMAX_SD59x18)) {\\n revert CastingErrors.PRBMath_UD60x18_IntoSD59x18_Overflow(x);\\n }\\n result = SD59x18.wrap(int256(xUint));\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev This is basically an alias for {unwrap}.\\nfunction intoUint256(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint128.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT128`.\\nfunction intoUint128(UD60x18 x) pure returns (uint128 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT128) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint128_Overflow(x);\\n }\\n result = uint128(xUint);\\n}\\n\\n/// @notice Casts a UD60x18 number into uint40.\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UINT40`.\\nfunction intoUint40(UD60x18 x) pure returns (uint40 result) {\\n uint256 xUint = UD60x18.unwrap(x);\\n if (xUint > MAX_UINT40) {\\n revert CastingErrors.PRBMath_UD60x18_IntoUint40_Overflow(x);\\n }\\n result = uint40(xUint);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Alias for {wrap}.\\nfunction ud60x18(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\\n/// @notice Unwraps a UD60x18 number into uint256.\\nfunction unwrap(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x);\\n}\\n\\n/// @notice Wraps a uint256 number into the UD60x18 value type.\\nfunction wrap(uint256 x) pure returns (UD60x18 result) {\\n result = UD60x18.wrap(x);\\n}\\n\",\"keccak256\":\"0x5bb532da36921cbdac64d1f16de5d366ef1f664502e3b7c07d0ad06917551f85\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Constants.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n// NOTICE: the \\\"u\\\" prefix stands for \\\"unwrapped\\\".\\n\\n/// @dev Euler's number as a UD60x18 number.\\nUD60x18 constant E = UD60x18.wrap(2_718281828459045235);\\n\\n/// @dev The maximum input permitted in {exp}.\\nuint256 constant uEXP_MAX_INPUT = 133_084258667509499440;\\nUD60x18 constant EXP_MAX_INPUT = UD60x18.wrap(uEXP_MAX_INPUT);\\n\\n/// @dev The maximum input permitted in {exp2}.\\nuint256 constant uEXP2_MAX_INPUT = 192e18 - 1;\\nUD60x18 constant EXP2_MAX_INPUT = UD60x18.wrap(uEXP2_MAX_INPUT);\\n\\n/// @dev Half the UNIT number.\\nuint256 constant uHALF_UNIT = 0.5e18;\\nUD60x18 constant HALF_UNIT = UD60x18.wrap(uHALF_UNIT);\\n\\n/// @dev $log_2(10)$ as a UD60x18 number.\\nuint256 constant uLOG2_10 = 3_321928094887362347;\\nUD60x18 constant LOG2_10 = UD60x18.wrap(uLOG2_10);\\n\\n/// @dev $log_2(e)$ as a UD60x18 number.\\nuint256 constant uLOG2_E = 1_442695040888963407;\\nUD60x18 constant LOG2_E = UD60x18.wrap(uLOG2_E);\\n\\n/// @dev The maximum value a UD60x18 number can have.\\nuint256 constant uMAX_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_584007913129639935;\\nUD60x18 constant MAX_UD60x18 = UD60x18.wrap(uMAX_UD60x18);\\n\\n/// @dev The maximum whole value a UD60x18 number can have.\\nuint256 constant uMAX_WHOLE_UD60x18 = 115792089237316195423570985008687907853269984665640564039457_000000000000000000;\\nUD60x18 constant MAX_WHOLE_UD60x18 = UD60x18.wrap(uMAX_WHOLE_UD60x18);\\n\\n/// @dev PI as a UD60x18 number.\\nUD60x18 constant PI = UD60x18.wrap(3_141592653589793238);\\n\\n/// @dev The unit number, which gives the decimal precision of UD60x18.\\nuint256 constant uUNIT = 1e18;\\nUD60x18 constant UNIT = UD60x18.wrap(uUNIT);\\n\\n/// @dev The unit number squared.\\nuint256 constant uUNIT_SQUARED = 1e36;\\nUD60x18 constant UNIT_SQUARED = UD60x18.wrap(uUNIT_SQUARED);\\n\\n/// @dev Zero as a UD60x18 number.\\nUD60x18 constant ZERO = UD60x18.wrap(0);\\n\",\"keccak256\":\"0x2b80d26153d3fdcfb3a9ca772d9309d31ed1275f5b8b54c3ffb54d3652b37d90\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Conversions.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { uMAX_UD60x18, uUNIT } from \\\"./Constants.sol\\\";\\nimport { PRBMath_UD60x18_Convert_Overflow } from \\\"./Errors.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Converts a UD60x18 number to a simple integer by dividing it by `UNIT`.\\n/// @dev The result is rounded toward zero.\\n/// @param x The UD60x18 number to convert.\\n/// @return result The same number in basic integer form.\\nfunction convert(UD60x18 x) pure returns (uint256 result) {\\n result = UD60x18.unwrap(x) / uUNIT;\\n}\\n\\n/// @notice Converts a simple integer to UD60x18 by multiplying it by `UNIT`.\\n///\\n/// @dev Requirements:\\n/// - x must be less than or equal to `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The basic integer to convert.\\n/// @param result The same number converted to UD60x18.\\nfunction convert(uint256 x) pure returns (UD60x18 result) {\\n if (x > uMAX_UD60x18 / uUNIT) {\\n revert PRBMath_UD60x18_Convert_Overflow(x);\\n }\\n unchecked {\\n result = UD60x18.wrap(x * uUNIT);\\n }\\n}\\n\",\"keccak256\":\"0xaf7fc2523413822de3b66ba339fe2884fb3b8c6f6cf38ec90a2c3e3aae71df6b\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Errors.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Thrown when ceiling a number overflows UD60x18.\\nerror PRBMath_UD60x18_Ceil_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when converting a basic integer to the fixed-point format overflows UD60x18.\\nerror PRBMath_UD60x18_Convert_Overflow(uint256 x);\\n\\n/// @notice Thrown when taking the natural exponent of a base greater than 133_084258667509499441.\\nerror PRBMath_UD60x18_Exp_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the binary exponent of a base greater than 192e18.\\nerror PRBMath_UD60x18_Exp2_InputTooBig(UD60x18 x);\\n\\n/// @notice Thrown when taking the geometric mean of two numbers and multiplying them overflows UD60x18.\\nerror PRBMath_UD60x18_Gm_Overflow(UD60x18 x, UD60x18 y);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD1x18.\\nerror PRBMath_UD60x18_IntoSD1x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in SD59x18.\\nerror PRBMath_UD60x18_IntoSD59x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in UD2x18.\\nerror PRBMath_UD60x18_IntoUD2x18_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint128.\\nerror PRBMath_UD60x18_IntoUint128_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when trying to cast a UD60x18 number that doesn't fit in uint40.\\nerror PRBMath_UD60x18_IntoUint40_Overflow(UD60x18 x);\\n\\n/// @notice Thrown when taking the logarithm of a number less than 1.\\nerror PRBMath_UD60x18_Log_InputTooSmall(UD60x18 x);\\n\\n/// @notice Thrown when calculating the square root overflows UD60x18.\\nerror PRBMath_UD60x18_Sqrt_Overflow(UD60x18 x);\\n\",\"keccak256\":\"0xa8c60d4066248df22c49c882873efbc017344107edabc48c52209abbc39cb1e3\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/// @notice Implements the checked addition operation (+) in the UD60x18 type.\\nfunction add(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() + y.unwrap());\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & bits);\\n}\\n\\n/// @notice Implements the AND (&) bitwise operation in the UD60x18 type.\\nfunction and2(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() & y.unwrap());\\n}\\n\\n/// @notice Implements the equal operation (==) in the UD60x18 type.\\nfunction eq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() == y.unwrap();\\n}\\n\\n/// @notice Implements the greater than operation (>) in the UD60x18 type.\\nfunction gt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() > y.unwrap();\\n}\\n\\n/// @notice Implements the greater than or equal to operation (>=) in the UD60x18 type.\\nfunction gte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() >= y.unwrap();\\n}\\n\\n/// @notice Implements a zero comparison check function in the UD60x18 type.\\nfunction isZero(UD60x18 x) pure returns (bool result) {\\n // This wouldn't work if x could be negative.\\n result = x.unwrap() == 0;\\n}\\n\\n/// @notice Implements the left shift operation (<<) in the UD60x18 type.\\nfunction lshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() << bits);\\n}\\n\\n/// @notice Implements the lower than operation (<) in the UD60x18 type.\\nfunction lt(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() < y.unwrap();\\n}\\n\\n/// @notice Implements the lower than or equal to operation (<=) in the UD60x18 type.\\nfunction lte(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() <= y.unwrap();\\n}\\n\\n/// @notice Implements the checked modulo operation (%) in the UD60x18 type.\\nfunction mod(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() % y.unwrap());\\n}\\n\\n/// @notice Implements the not equal operation (!=) in the UD60x18 type.\\nfunction neq(UD60x18 x, UD60x18 y) pure returns (bool result) {\\n result = x.unwrap() != y.unwrap();\\n}\\n\\n/// @notice Implements the NOT (~) bitwise operation in the UD60x18 type.\\nfunction not(UD60x18 x) pure returns (UD60x18 result) {\\n result = wrap(~x.unwrap());\\n}\\n\\n/// @notice Implements the OR (|) bitwise operation in the UD60x18 type.\\nfunction or(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() | y.unwrap());\\n}\\n\\n/// @notice Implements the right shift operation (>>) in the UD60x18 type.\\nfunction rshift(UD60x18 x, uint256 bits) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() >> bits);\\n}\\n\\n/// @notice Implements the checked subtraction operation (-) in the UD60x18 type.\\nfunction sub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() - y.unwrap());\\n}\\n\\n/// @notice Implements the unchecked addition operation (+) in the UD60x18 type.\\nfunction uncheckedAdd(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() + y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the unchecked subtraction operation (-) in the UD60x18 type.\\nfunction uncheckedSub(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(x.unwrap() - y.unwrap());\\n }\\n}\\n\\n/// @notice Implements the XOR (^) bitwise operation in the UD60x18 type.\\nfunction xor(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(x.unwrap() ^ y.unwrap());\\n}\\n\",\"keccak256\":\"0xf5faff881391d2c060029499a666cc5f0bea90a213150bb476fae8f02a5df268\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"../Common.sol\\\" as Common;\\nimport \\\"./Errors.sol\\\" as Errors;\\nimport { wrap } from \\\"./Casting.sol\\\";\\nimport {\\n uEXP_MAX_INPUT,\\n uEXP2_MAX_INPUT,\\n uHALF_UNIT,\\n uLOG2_10,\\n uLOG2_E,\\n uMAX_UD60x18,\\n uMAX_WHOLE_UD60x18,\\n UNIT,\\n uUNIT,\\n uUNIT_SQUARED,\\n ZERO\\n} from \\\"./Constants.sol\\\";\\nimport { UD60x18 } from \\\"./ValueType.sol\\\";\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n/// @notice Calculates the arithmetic average of x and y using the following formula:\\n///\\n/// $$\\n/// avg(x, y) = (x & y) + ((xUint ^ yUint) / 2)\\n/// $$\\n///\\n/// In English, this is what this formula does:\\n///\\n/// 1. AND x and y.\\n/// 2. Calculate half of XOR x and y.\\n/// 3. Add the two results together.\\n///\\n/// This technique is known as SWAR, which stands for \\\"SIMD within a register\\\". You can read more about it here:\\n/// https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The arithmetic average as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction avg(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n unchecked {\\n result = wrap((xUint & yUint) + ((xUint ^ yUint) >> 1));\\n }\\n}\\n\\n/// @notice Yields the smallest whole number greater than or equal to x.\\n///\\n/// @dev This is optimized for fractional value inputs, because for every whole value there are (1e18 - 1) fractional\\n/// counterparts. See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n///\\n/// Requirements:\\n/// - x must be less than or equal to `MAX_WHOLE_UD60x18`.\\n///\\n/// @param x The UD60x18 number to ceil.\\n/// @param result The smallest whole number greater than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ceil(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint > uMAX_WHOLE_UD60x18) {\\n revert Errors.PRBMath_UD60x18_Ceil_Overflow(x);\\n }\\n\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `UNIT - remainder`.\\n let delta := sub(uUNIT, remainder)\\n\\n // Equivalent to `x + remainder > 0 ? delta : 0`.\\n result := add(x, mul(delta, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Divides two UD60x18 numbers, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @param x The numerator as a UD60x18 number.\\n/// @param y The denominator as a UD60x18 number.\\n/// @param result The quotient as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction div(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv(x.unwrap(), uUNIT, y.unwrap()));\\n}\\n\\n/// @notice Calculates the natural exponent of x using the following formula:\\n///\\n/// $$\\n/// e^x = 2^{x * log_2{e}}\\n/// $$\\n///\\n/// @dev Requirements:\\n/// - x must be less than 133_084258667509499441.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // This check prevents values greater than 192e18 from being passed to {exp2}.\\n if (xUint > uEXP_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp_InputTooBig(x);\\n }\\n\\n unchecked {\\n // Inline the fixed-point multiplication to save gas.\\n uint256 doubleUnitProduct = xUint * uLOG2_E;\\n result = exp2(wrap(doubleUnitProduct / uUNIT));\\n }\\n}\\n\\n/// @notice Calculates the binary exponent of x using the binary fraction method.\\n///\\n/// @dev See https://ethereum.stackexchange.com/q/79903/24693\\n///\\n/// Requirements:\\n/// - x must be less than 192e18.\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction exp2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n // Numbers greater than or equal to 192e18 don't fit in the 192.64-bit format.\\n if (xUint > uEXP2_MAX_INPUT) {\\n revert Errors.PRBMath_UD60x18_Exp2_InputTooBig(x);\\n }\\n\\n // Convert x to the 192.64-bit fixed-point format.\\n uint256 x_192x64 = (xUint << 64) / uUNIT;\\n\\n // Pass x to the {Common.exp2} function, which uses the 192.64-bit fixed-point number representation.\\n result = wrap(Common.exp2(x_192x64));\\n}\\n\\n/// @notice Yields the greatest whole number less than or equal to x.\\n/// @dev Optimized for fractional value inputs, because every whole value has (1e18 - 1) fractional counterparts.\\n/// See https://en.wikipedia.org/wiki/Floor_and_ceiling_functions.\\n/// @param x The UD60x18 number to floor.\\n/// @param result The greatest whole number less than or equal to x, as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction floor(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n // Equivalent to `x % UNIT`.\\n let remainder := mod(x, uUNIT)\\n\\n // Equivalent to `x - remainder > 0 ? remainder : 0)`.\\n result := sub(x, mul(remainder, gt(remainder, 0)))\\n }\\n}\\n\\n/// @notice Yields the excess beyond the floor of x using the odd function definition.\\n/// @dev See https://en.wikipedia.org/wiki/Fractional_part.\\n/// @param x The UD60x18 number to get the fractional part of.\\n/// @param result The fractional part of x as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction frac(UD60x18 x) pure returns (UD60x18 result) {\\n assembly (\\\"memory-safe\\\") {\\n result := mod(x, uUNIT)\\n }\\n}\\n\\n/// @notice Calculates the geometric mean of x and y, i.e. $\\\\sqrt{x * y}$, rounding down.\\n///\\n/// @dev Requirements:\\n/// - x * y must fit in UD60x18.\\n///\\n/// @param x The first operand as a UD60x18 number.\\n/// @param y The second operand as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction gm(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n if (xUint == 0 || yUint == 0) {\\n return ZERO;\\n }\\n\\n unchecked {\\n // Checking for overflow this way is faster than letting Solidity do it.\\n uint256 xyUint = xUint * yUint;\\n if (xyUint / xUint != yUint) {\\n revert Errors.PRBMath_UD60x18_Gm_Overflow(x, y);\\n }\\n\\n // We don't need to multiply the result by `UNIT` here because the x*y product picked up a factor of `UNIT`\\n // during multiplication. See the comments in {Common.sqrt}.\\n result = wrap(Common.sqrt(xyUint));\\n }\\n}\\n\\n/// @notice Calculates the inverse of x.\\n///\\n/// @dev Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must not be zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the inverse.\\n/// @return result The inverse as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction inv(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n result = wrap(uUNIT_SQUARED / x.unwrap());\\n }\\n}\\n\\n/// @notice Calculates the natural logarithm of x using the following formula:\\n///\\n/// $$\\n/// ln{x} = log_2{x} / log_2{e}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n/// - The precision isn't sufficiently fine-grained to return exactly `UNIT` when the input is `E`.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the natural logarithm.\\n/// @return result The natural logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction ln(UD60x18 x) pure returns (UD60x18 result) {\\n unchecked {\\n // Inline the fixed-point multiplication to save gas. This is overflow-safe because the maximum value that\\n // {log2} can return is ~196_205294292027477728.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_E);\\n }\\n}\\n\\n/// @notice Calculates the common logarithm of x using the following formula:\\n///\\n/// $$\\n/// log_{10}{x} = log_2{x} / log_2{10}\\n/// $$\\n///\\n/// However, if x is an exact power of ten, a hard coded value is returned.\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {log2}.\\n///\\n/// @param x The UD60x18 number for which to calculate the common logarithm.\\n/// @return result The common logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log10(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n // Note that the `mul` in this assembly block is the standard multiplication operation, not {UD60x18.mul}.\\n // prettier-ignore\\n assembly (\\\"memory-safe\\\") {\\n switch x\\n case 1 { result := mul(uUNIT, sub(0, 18)) }\\n case 10 { result := mul(uUNIT, sub(1, 18)) }\\n case 100 { result := mul(uUNIT, sub(2, 18)) }\\n case 1000 { result := mul(uUNIT, sub(3, 18)) }\\n case 10000 { result := mul(uUNIT, sub(4, 18)) }\\n case 100000 { result := mul(uUNIT, sub(5, 18)) }\\n case 1000000 { result := mul(uUNIT, sub(6, 18)) }\\n case 10000000 { result := mul(uUNIT, sub(7, 18)) }\\n case 100000000 { result := mul(uUNIT, sub(8, 18)) }\\n case 1000000000 { result := mul(uUNIT, sub(9, 18)) }\\n case 10000000000 { result := mul(uUNIT, sub(10, 18)) }\\n case 100000000000 { result := mul(uUNIT, sub(11, 18)) }\\n case 1000000000000 { result := mul(uUNIT, sub(12, 18)) }\\n case 10000000000000 { result := mul(uUNIT, sub(13, 18)) }\\n case 100000000000000 { result := mul(uUNIT, sub(14, 18)) }\\n case 1000000000000000 { result := mul(uUNIT, sub(15, 18)) }\\n case 10000000000000000 { result := mul(uUNIT, sub(16, 18)) }\\n case 100000000000000000 { result := mul(uUNIT, sub(17, 18)) }\\n case 1000000000000000000 { result := 0 }\\n case 10000000000000000000 { result := uUNIT }\\n case 100000000000000000000 { result := mul(uUNIT, 2) }\\n case 1000000000000000000000 { result := mul(uUNIT, 3) }\\n case 10000000000000000000000 { result := mul(uUNIT, 4) }\\n case 100000000000000000000000 { result := mul(uUNIT, 5) }\\n case 1000000000000000000000000 { result := mul(uUNIT, 6) }\\n case 10000000000000000000000000 { result := mul(uUNIT, 7) }\\n case 100000000000000000000000000 { result := mul(uUNIT, 8) }\\n case 1000000000000000000000000000 { result := mul(uUNIT, 9) }\\n case 10000000000000000000000000000 { result := mul(uUNIT, 10) }\\n case 100000000000000000000000000000 { result := mul(uUNIT, 11) }\\n case 1000000000000000000000000000000 { result := mul(uUNIT, 12) }\\n case 10000000000000000000000000000000 { result := mul(uUNIT, 13) }\\n case 100000000000000000000000000000000 { result := mul(uUNIT, 14) }\\n case 1000000000000000000000000000000000 { result := mul(uUNIT, 15) }\\n case 10000000000000000000000000000000000 { result := mul(uUNIT, 16) }\\n case 100000000000000000000000000000000000 { result := mul(uUNIT, 17) }\\n case 1000000000000000000000000000000000000 { result := mul(uUNIT, 18) }\\n case 10000000000000000000000000000000000000 { result := mul(uUNIT, 19) }\\n case 100000000000000000000000000000000000000 { result := mul(uUNIT, 20) }\\n case 1000000000000000000000000000000000000000 { result := mul(uUNIT, 21) }\\n case 10000000000000000000000000000000000000000 { result := mul(uUNIT, 22) }\\n case 100000000000000000000000000000000000000000 { result := mul(uUNIT, 23) }\\n case 1000000000000000000000000000000000000000000 { result := mul(uUNIT, 24) }\\n case 10000000000000000000000000000000000000000000 { result := mul(uUNIT, 25) }\\n case 100000000000000000000000000000000000000000000 { result := mul(uUNIT, 26) }\\n case 1000000000000000000000000000000000000000000000 { result := mul(uUNIT, 27) }\\n case 10000000000000000000000000000000000000000000000 { result := mul(uUNIT, 28) }\\n case 100000000000000000000000000000000000000000000000 { result := mul(uUNIT, 29) }\\n case 1000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 30) }\\n case 10000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 31) }\\n case 100000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 32) }\\n case 1000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 33) }\\n case 10000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 34) }\\n case 100000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 35) }\\n case 1000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 36) }\\n case 10000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 37) }\\n case 100000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 38) }\\n case 1000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 39) }\\n case 10000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 40) }\\n case 100000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 41) }\\n case 1000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 42) }\\n case 10000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 43) }\\n case 100000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 44) }\\n case 1000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 45) }\\n case 10000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 46) }\\n case 100000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 47) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 48) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 49) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 50) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 51) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 52) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 53) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 54) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 55) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 56) }\\n case 1000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 57) }\\n case 10000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 58) }\\n case 100000000000000000000000000000000000000000000000000000000000000000000000000000 { result := mul(uUNIT, 59) }\\n default { result := uMAX_UD60x18 }\\n }\\n\\n if (result.unwrap() == uMAX_UD60x18) {\\n unchecked {\\n // Inline the fixed-point division to save gas.\\n result = wrap(log2(x).unwrap() * uUNIT / uLOG2_10);\\n }\\n }\\n}\\n\\n/// @notice Calculates the binary logarithm of x using the iterative approximation algorithm:\\n///\\n/// $$\\n/// log_2{x} = n + log_2{y}, \\\\text{ where } y = x*2^{-n}, \\\\ y \\\\in [1, 2)\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, the input is inverted:\\n///\\n/// $$\\n/// log_2{x} = -log_2{\\\\frac{1}{x}}\\n/// $$\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Binary_logarithm#Iterative_approximation\\n///\\n/// Notes:\\n/// - Due to the lossy precision of the iterative approximation, the results are not perfectly accurate to the last decimal.\\n///\\n/// Requirements:\\n/// - x must be greater than zero.\\n///\\n/// @param x The UD60x18 number for which to calculate the binary logarithm.\\n/// @return result The binary logarithm as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction log2(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n if (xUint < uUNIT) {\\n revert Errors.PRBMath_UD60x18_Log_InputTooSmall(x);\\n }\\n\\n unchecked {\\n // Calculate the integer part of the logarithm.\\n uint256 n = Common.msb(xUint / uUNIT);\\n\\n // This is the integer part of the logarithm as a UD60x18 number. The operation can't overflow because n\\n // n is at most 255 and UNIT is 1e18.\\n uint256 resultUint = n * uUNIT;\\n\\n // Calculate $y = x * 2^{-n}$.\\n uint256 y = xUint >> n;\\n\\n // If y is the unit number, the fractional part is zero.\\n if (y == uUNIT) {\\n return wrap(resultUint);\\n }\\n\\n // Calculate the fractional part via the iterative approximation.\\n // The `delta >>= 1` part is equivalent to `delta /= 2`, but shifting bits is more gas efficient.\\n uint256 DOUBLE_UNIT = 2e18;\\n for (uint256 delta = uHALF_UNIT; delta > 0; delta >>= 1) {\\n y = (y * y) / uUNIT;\\n\\n // Is y^2 >= 2e18 and so in the range [2e18, 4e18)?\\n if (y >= DOUBLE_UNIT) {\\n // Add the 2^{-m} factor to the logarithm.\\n resultUint += delta;\\n\\n // Halve y, which corresponds to z/2 in the Wikipedia article.\\n y >>= 1;\\n }\\n }\\n result = wrap(resultUint);\\n }\\n}\\n\\n/// @notice Multiplies two UD60x18 numbers together, returning a new UD60x18 number.\\n///\\n/// @dev Uses {Common.mulDiv} to enable overflow-safe multiplication and division.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv}.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {Common.mulDiv}.\\n///\\n/// @dev See the documentation in {Common.mulDiv18}.\\n/// @param x The multiplicand as a UD60x18 number.\\n/// @param y The multiplier as a UD60x18 number.\\n/// @return result The product as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction mul(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n result = wrap(Common.mulDiv18(x.unwrap(), y.unwrap()));\\n}\\n\\n/// @notice Raises x to the power of y.\\n///\\n/// For $1 \\\\leq x \\\\leq \\\\infty$, the following standard formula is used:\\n///\\n/// $$\\n/// x^y = 2^{log_2{x} * y}\\n/// $$\\n///\\n/// For $0 \\\\leq x \\\\lt 1$, since the unsigned {log2} is undefined, an equivalent formula is used:\\n///\\n/// $$\\n/// i = \\\\frac{1}{x}\\n/// w = 2^{log_2{i} * y}\\n/// x^y = \\\\frac{1}{w}\\n/// $$\\n///\\n/// @dev Notes:\\n/// - Refer to the notes in {log2} and {mul}.\\n/// - Returns `UNIT` for 0^0.\\n/// - It may not perform well with very small values of x. Consider using SD59x18 as an alternative.\\n///\\n/// Requirements:\\n/// - Refer to the requirements in {exp2}, {log2}, and {mul}.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a UD60x18 number.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction pow(UD60x18 x, UD60x18 y) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n uint256 yUint = y.unwrap();\\n\\n // If both x and y are zero, the result is `UNIT`. If just x is zero, the result is always zero.\\n if (xUint == 0) {\\n return yUint == 0 ? UNIT : ZERO;\\n }\\n // If x is `UNIT`, the result is always `UNIT`.\\n else if (xUint == uUNIT) {\\n return UNIT;\\n }\\n\\n // If y is zero, the result is always `UNIT`.\\n if (yUint == 0) {\\n return UNIT;\\n }\\n // If y is `UNIT`, the result is always x.\\n else if (yUint == uUNIT) {\\n return x;\\n }\\n\\n // If x is greater than `UNIT`, use the standard formula.\\n if (xUint > uUNIT) {\\n result = exp2(mul(log2(x), y));\\n }\\n // Conversely, if x is less than `UNIT`, use the equivalent formula.\\n else {\\n UD60x18 i = wrap(uUNIT_SQUARED / xUint);\\n UD60x18 w = exp2(mul(log2(i), y));\\n result = wrap(uUNIT_SQUARED / w.unwrap());\\n }\\n}\\n\\n/// @notice Raises x (a UD60x18 number) to the power y (an unsigned basic integer) using the well-known\\n/// algorithm \\\"exponentiation by squaring\\\".\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Exponentiation_by_squaring.\\n///\\n/// Notes:\\n/// - Refer to the notes in {Common.mulDiv18}.\\n/// - Returns `UNIT` for 0^0.\\n///\\n/// Requirements:\\n/// - The result must fit in UD60x18.\\n///\\n/// @param x The base as a UD60x18 number.\\n/// @param y The exponent as a uint256.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction powu(UD60x18 x, uint256 y) pure returns (UD60x18 result) {\\n // Calculate the first iteration of the loop in advance.\\n uint256 xUint = x.unwrap();\\n uint256 resultUint = y & 1 > 0 ? xUint : uUNIT;\\n\\n // Equivalent to `for(y /= 2; y > 0; y /= 2)`.\\n for (y >>= 1; y > 0; y >>= 1) {\\n xUint = Common.mulDiv18(xUint, xUint);\\n\\n // Equivalent to `y % 2 == 1`.\\n if (y & 1 > 0) {\\n resultUint = Common.mulDiv18(resultUint, xUint);\\n }\\n }\\n result = wrap(resultUint);\\n}\\n\\n/// @notice Calculates the square root of x using the Babylonian method.\\n///\\n/// @dev See https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method.\\n///\\n/// Notes:\\n/// - The result is rounded toward zero.\\n///\\n/// Requirements:\\n/// - x must be less than `MAX_UD60x18 / UNIT`.\\n///\\n/// @param x The UD60x18 number for which to calculate the square root.\\n/// @return result The result as a UD60x18 number.\\n/// @custom:smtchecker abstract-function-nondet\\nfunction sqrt(UD60x18 x) pure returns (UD60x18 result) {\\n uint256 xUint = x.unwrap();\\n\\n unchecked {\\n if (xUint > uMAX_UD60x18 / uUNIT) {\\n revert Errors.PRBMath_UD60x18_Sqrt_Overflow(x);\\n }\\n // Multiply x by `UNIT` to account for the factor of `UNIT` picked up when multiplying two UD60x18 numbers.\\n // In this case, the two numbers are both the square root.\\n result = wrap(Common.sqrt(xUint * uUNIT));\\n }\\n}\\n\",\"keccak256\":\"0x462144667aac3f96d5f8dba7aa68fe4c5a3f61e1d7bbbc81bee21168817f9c09\",\"license\":\"MIT\"},\"@prb/math/src/ud60x18/ValueType.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.19;\\n\\nimport \\\"./Casting.sol\\\" as Casting;\\nimport \\\"./Helpers.sol\\\" as Helpers;\\nimport \\\"./Math.sol\\\" as Math;\\n\\n/// @notice The unsigned 60.18-decimal fixed-point number representation, which can have up to 60 digits and up to 18\\n/// decimals. The values of this are bound by the minimum and the maximum values permitted by the Solidity type uint256.\\n/// @dev The value type is defined here so it can be imported in all other files.\\ntype UD60x18 is uint256;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n CASTING\\n//////////////////////////////////////////////////////////////////////////*/\\n\\nusing {\\n Casting.intoSD1x18,\\n Casting.intoUD2x18,\\n Casting.intoSD59x18,\\n Casting.intoUint128,\\n Casting.intoUint256,\\n Casting.intoUint40,\\n Casting.unwrap\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n MATHEMATICAL FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Math.avg,\\n Math.ceil,\\n Math.div,\\n Math.exp,\\n Math.exp2,\\n Math.floor,\\n Math.frac,\\n Math.gm,\\n Math.inv,\\n Math.ln,\\n Math.log10,\\n Math.log2,\\n Math.mul,\\n Math.pow,\\n Math.powu,\\n Math.sqrt\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n HELPER FUNCTIONS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes the functions in this library callable on the UD60x18 type.\\nusing {\\n Helpers.add,\\n Helpers.and,\\n Helpers.eq,\\n Helpers.gt,\\n Helpers.gte,\\n Helpers.isZero,\\n Helpers.lshift,\\n Helpers.lt,\\n Helpers.lte,\\n Helpers.mod,\\n Helpers.neq,\\n Helpers.not,\\n Helpers.or,\\n Helpers.rshift,\\n Helpers.sub,\\n Helpers.uncheckedAdd,\\n Helpers.uncheckedSub,\\n Helpers.xor\\n} for UD60x18 global;\\n\\n/*//////////////////////////////////////////////////////////////////////////\\n OPERATORS\\n//////////////////////////////////////////////////////////////////////////*/\\n\\n// The global \\\"using for\\\" directive makes it possible to use these operators on the UD60x18 type.\\nusing {\\n Helpers.add as +,\\n Helpers.and2 as &,\\n Math.div as /,\\n Helpers.eq as ==,\\n Helpers.gt as >,\\n Helpers.gte as >=,\\n Helpers.lt as <,\\n Helpers.lte as <=,\\n Helpers.or as |,\\n Helpers.mod as %,\\n Math.mul as *,\\n Helpers.neq as !=,\\n Helpers.not as ~,\\n Helpers.sub as -,\\n Helpers.xor as ^\\n} for UD60x18 global;\\n\",\"keccak256\":\"0xdd873b5124180d9b71498b3a7fe93b1c08c368bec741f7d5f8e17f78a0b70f31\",\"license\":\"MIT\"},\"contracts/DecentSablierStreamManagement.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.28;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {ISablierV2Lockup} from \\\"./interfaces/sablier/full/ISablierV2Lockup.sol\\\";\\nimport {Lockup} from \\\"./interfaces/sablier/full/types/DataTypes.sol\\\";\\n\\ncontract DecentSablierStreamManagement {\\n string public constant NAME = \\\"DecentSablierStreamManagement\\\";\\n\\n function withdrawMaxFromStream(\\n ISablierV2Lockup sablier,\\n address recipientHatAccount,\\n uint256 streamId,\\n address to\\n ) public {\\n // Check if there are funds to withdraw\\n uint128 withdrawableAmount = sablier.withdrawableAmountOf(streamId);\\n if (withdrawableAmount == 0) {\\n return;\\n }\\n\\n // Proxy the Sablier withdrawMax call through IAvatar (Safe)\\n IAvatar(msg.sender).execTransactionFromModule(\\n recipientHatAccount,\\n 0,\\n abi.encodeWithSignature(\\n \\\"execute(address,uint256,bytes,uint8)\\\",\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"withdrawMax(uint256,address)\\\",\\n streamId,\\n to\\n ),\\n 0\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function cancelStream(ISablierV2Lockup sablier, uint256 streamId) public {\\n // Check if the stream can be cancelled\\n Lockup.Status streamStatus = sablier.statusOf(streamId);\\n if (\\n streamStatus != Lockup.Status.PENDING &&\\n streamStatus != Lockup.Status.STREAMING\\n ) {\\n return;\\n }\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablier),\\n 0,\\n abi.encodeWithSignature(\\\"cancel(uint256)\\\", streamId),\\n Enum.Operation.Call\\n );\\n }\\n}\\n\",\"keccak256\":\"0xf36be7e97936d82de0035b8bda2c53dbc52b9ca3b8efe305540a7632cb6fe6ab\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/IAdminable.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\n/// @title IAdminable\\n/// @notice Contract module that provides a basic access control mechanism, with an admin that can be\\n/// granted exclusive access to specific functions. The inheriting contract must set the initial admin\\n/// in the constructor.\\ninterface IAdminable {\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin is transferred.\\n /// @param oldAdmin The address of the old admin.\\n /// @param newAdmin The address of the new admin.\\n event TransferAdmin(address indexed oldAdmin, address indexed newAdmin);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice The address of the admin account or contract.\\n function admin() external view returns (address);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Transfers the contract admin to a new address.\\n ///\\n /// @dev Notes:\\n /// - Does not revert if the admin is the same.\\n /// - This function can potentially leave the contract without an admin, thereby removing any\\n /// functionality that is only available to the admin.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newAdmin The address of the new admin.\\n function transferAdmin(address newAdmin) external;\\n}\\n\",\"keccak256\":\"0xa279c49e51228b571329164e36250e82b2c1378e8b549194ab7dd90fca9c3b2b\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/IERC4096.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4906.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/interfaces/IERC165.sol\\\";\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\n\\n/// @title ERC-721 Metadata Update Extension\\ninterface IERC4906 is IERC165, IERC721 {\\n /// @dev This event emits when the metadata of a token is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFT.\\n event MetadataUpdate(uint256 _tokenId);\\n\\n /// @dev This event emits when the metadata of a range of tokens is changed.\\n /// So that the third-party platforms such as NFT market could\\n /// timely update the images and related attributes of the NFTs.\\n event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);\\n}\\n\",\"keccak256\":\"0xa34b9c52cbe36be860244f52256f1b05badf0cb797d208664b87337610d0e82d\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/full/ISablierV2Lockup.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC4906} from \\\"./IERC4096.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\nimport {Lockup} from \\\"./types/DataTypes.sol\\\";\\nimport {IAdminable} from \\\"./IAdminable.sol\\\";\\nimport {ISablierV2NFTDescriptor} from \\\"./ISablierV2NFTDescriptor.sol\\\";\\n\\n/// @title ISablierV2Lockup\\n/// @notice Common logic between all Sablier V2 Lockup contracts.\\ninterface ISablierV2Lockup is\\n IAdminable, // 0 inherited components\\n IERC4906, // 2 inherited components\\n IERC721Metadata // 2 inherited components\\n{\\n /*//////////////////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Emitted when the admin allows a new recipient contract to hook to Sablier.\\n /// @param admin The address of the current contract admin.\\n /// @param recipient The address of the recipient contract put on the allowlist.\\n event AllowToHook(address indexed admin, address recipient);\\n\\n /// @notice Emitted when a stream is canceled.\\n /// @param streamId The ID of the stream.\\n /// @param sender The address of the stream's sender.\\n /// @param recipient The address of the stream's recipient.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param senderAmount The amount of assets refunded to the stream's sender, denoted in units of the asset's\\n /// decimals.\\n /// @param recipientAmount The amount of assets left for the stream's recipient to withdraw, denoted in units of the\\n /// asset's decimals.\\n event CancelLockupStream(\\n uint256 streamId,\\n address indexed sender,\\n address indexed recipient,\\n IERC20 indexed asset,\\n uint128 senderAmount,\\n uint128 recipientAmount\\n );\\n\\n /// @notice Emitted when a sender gives up the right to cancel a stream.\\n /// @param streamId The ID of the stream.\\n event RenounceLockupStream(uint256 indexed streamId);\\n\\n /// @notice Emitted when the admin sets a new NFT descriptor contract.\\n /// @param admin The address of the current contract admin.\\n /// @param oldNFTDescriptor The address of the old NFT descriptor contract.\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n event SetNFTDescriptor(\\n address indexed admin,\\n ISablierV2NFTDescriptor oldNFTDescriptor,\\n ISablierV2NFTDescriptor newNFTDescriptor\\n );\\n\\n /// @notice Emitted when assets are withdrawn from a stream.\\n /// @param streamId The ID of the stream.\\n /// @param to The address that has received the withdrawn assets.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param amount The amount of assets withdrawn, denoted in units of the asset's decimals.\\n event WithdrawFromLockupStream(\\n uint256 indexed streamId,\\n address indexed to,\\n IERC20 indexed asset,\\n uint128 amount\\n );\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Retrieves the address of the ERC-20 asset to be distributed.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getAsset(uint256 streamId) external view returns (IERC20 asset);\\n\\n /// @notice Retrieves the amount deposited in the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getDepositedAmount(\\n uint256 streamId\\n ) external view returns (uint128 depositedAmount);\\n\\n /// @notice Retrieves the stream's end time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getEndTime(\\n uint256 streamId\\n ) external view returns (uint40 endTime);\\n\\n /// @notice Retrieves the stream's recipient.\\n /// @dev Reverts if the NFT has been burned.\\n /// @param streamId The stream ID for the query.\\n function getRecipient(\\n uint256 streamId\\n ) external view returns (address recipient);\\n\\n /// @notice Retrieves the amount refunded to the sender after a cancellation, denoted in units of the asset's\\n /// decimals. This amount is always zero unless the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getRefundedAmount(\\n uint256 streamId\\n ) external view returns (uint128 refundedAmount);\\n\\n /// @notice Retrieves the stream's sender.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getSender(uint256 streamId) external view returns (address sender);\\n\\n /// @notice Retrieves the stream's start time, which is a Unix timestamp.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getStartTime(\\n uint256 streamId\\n ) external view returns (uint40 startTime);\\n\\n /// @notice Retrieves the amount withdrawn from the stream, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function getWithdrawnAmount(\\n uint256 streamId\\n ) external view returns (uint128 withdrawnAmount);\\n\\n /// @notice Retrieves a flag indicating whether the provided address is a contract allowed to hook to Sablier\\n /// when a stream is canceled or when assets are withdrawn.\\n /// @dev See {ISablierLockupRecipient} for more information.\\n function isAllowedToHook(\\n address recipient\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream can be canceled. When the stream is cold, this\\n /// flag is always `false`.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCancelable(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is cold, i.e. settled, canceled, or depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isCold(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is depleted.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isDepleted(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream exists.\\n /// @dev Does not revert if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isStream(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream NFT can be transferred.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isTransferable(\\n uint256 streamId\\n ) external view returns (bool result);\\n\\n /// @notice Retrieves a flag indicating whether the stream is warm, i.e. either pending or streaming.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function isWarm(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Retrieves the maximum broker fee that can be charged by the broker, denoted as a fixed-point\\n /// number where 1e18 is 100%.\\n /// @dev This value is hard coded as a constant.\\n function MAX_BROKER_FEE() external view returns (UD60x18);\\n\\n /// @notice Counter for stream IDs, used in the create functions.\\n function nextStreamId() external view returns (uint256);\\n\\n /// @notice Contract that generates the non-fungible token URI.\\n function nftDescriptor() external view returns (ISablierV2NFTDescriptor);\\n\\n /// @notice Calculates the amount that the sender would be refunded if the stream were canceled, denoted in units\\n /// of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function refundableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 refundableAmount);\\n\\n /// @notice Retrieves the stream's status.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function statusOf(\\n uint256 streamId\\n ) external view returns (Lockup.Status status);\\n\\n /// @notice Calculates the amount streamed to the recipient, denoted in units of the asset's decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n ///\\n /// Notes:\\n /// - Upon cancellation of the stream, the amount streamed is calculated as the difference between the deposited\\n /// amount and the refunded amount. Ultimately, when the stream becomes depleted, the streamed amount is equivalent\\n /// to the total amount withdrawn.\\n ///\\n /// @param streamId The stream ID for the query.\\n function streamedAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 streamedAmount);\\n\\n /// @notice Retrieves a flag indicating whether the stream was canceled.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function wasCanceled(uint256 streamId) external view returns (bool result);\\n\\n /// @notice Calculates the amount that the recipient can withdraw from the stream, denoted in units of the asset's\\n /// decimals.\\n /// @dev Reverts if `streamId` references a null stream.\\n /// @param streamId The stream ID for the query.\\n function withdrawableAmountOf(\\n uint256 streamId\\n ) external view returns (uint128 withdrawableAmount);\\n\\n /*//////////////////////////////////////////////////////////////////////////\\n NON-CONSTANT FUNCTIONS\\n //////////////////////////////////////////////////////////////////////////*/\\n\\n /// @notice Allows a recipient contract to hook to Sablier when a stream is canceled or when assets are withdrawn.\\n /// Useful for implementing contracts that hold streams on behalf of users, such as vaults or staking contracts.\\n ///\\n /// @dev Emits an {AllowToHook} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the contract is already on the allowlist.\\n /// - This is an irreversible operation. The contract cannot be removed from the allowlist.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n /// - `recipient` must have a non-zero code size.\\n /// - `recipient` must implement {ISablierLockupRecipient}.\\n ///\\n /// @param recipient The address of the contract to allow for hooks.\\n function allowToHook(address recipient) external;\\n\\n /// @notice Burns the NFT associated with the stream.\\n ///\\n /// @dev Emits a {Transfer} event.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a depleted stream.\\n /// - The NFT must exist.\\n /// - `msg.sender` must be either the NFT owner or an approved third party.\\n ///\\n /// @param streamId The ID of the stream NFT to burn.\\n function burn(uint256 streamId) external;\\n\\n /// @notice Cancels the stream and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits a {Transfer}, {CancelLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - If there any assets left for the recipient to withdraw, the stream is marked as canceled. Otherwise, the\\n /// stream is marked as depleted.\\n /// - This function attempts to invoke a hook on the recipient, if the resolved address is a contract.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - The stream must be warm and cancelable.\\n /// - `msg.sender` must be the stream's sender.\\n ///\\n /// @param streamId The ID of the stream to cancel.\\n function cancel(uint256 streamId) external;\\n\\n /// @notice Cancels multiple streams and refunds any remaining assets to the sender.\\n ///\\n /// @dev Emits multiple {Transfer}, {CancelLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {cancel}.\\n ///\\n /// Requirements:\\n /// - All requirements from {cancel} must be met for each stream.\\n ///\\n /// @param streamIds The IDs of the streams to cancel.\\n function cancelMultiple(uint256[] calldata streamIds) external;\\n\\n /// @notice Removes the right of the stream's sender to cancel the stream.\\n ///\\n /// @dev Emits a {RenounceLockupStream} and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This is an irreversible operation.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must reference a warm stream.\\n /// - `msg.sender` must be the stream's sender.\\n /// - The stream must be cancelable.\\n ///\\n /// @param streamId The ID of the stream to renounce.\\n function renounce(uint256 streamId) external;\\n\\n /// @notice Sets a new NFT descriptor contract, which produces the URI describing the Sablier stream NFTs.\\n ///\\n /// @dev Emits a {SetNFTDescriptor} and {BatchMetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Does not revert if the NFT descriptor is the same.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the contract admin.\\n ///\\n /// @param newNFTDescriptor The address of the new NFT descriptor contract.\\n function setNFTDescriptor(\\n ISablierV2NFTDescriptor newNFTDescriptor\\n ) external;\\n\\n /// @notice Withdraws the provided amount of assets from the stream to the `to` address.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of the stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - `streamId` must not reference a null or depleted stream.\\n /// - `to` must not be the zero address.\\n /// - `amount` must be greater than zero and must not exceed the withdrawable amount.\\n /// - `to` must be the recipient if `msg.sender` is not the stream's recipient or an approved third party.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @param amount The amount to withdraw, denoted in units of the asset's decimals.\\n function withdraw(uint256 streamId, address to, uint128 amount) external;\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the provided address `to`.\\n ///\\n /// @dev Emits a {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} event.\\n ///\\n /// Notes:\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - Refer to the requirements in {withdraw}.\\n ///\\n /// @param streamId The ID of the stream to withdraw from.\\n /// @param to The address receiving the withdrawn assets.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMax(\\n uint256 streamId,\\n address to\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws the maximum withdrawable amount from the stream to the current recipient, and transfers the\\n /// NFT to `newRecipient`.\\n ///\\n /// @dev Emits a {WithdrawFromLockupStream} and a {Transfer} event.\\n ///\\n /// Notes:\\n /// - If the withdrawable amount is zero, the withdrawal is skipped.\\n /// - Refer to the notes in {withdraw}.\\n ///\\n /// Requirements:\\n /// - `msg.sender` must be the stream's recipient.\\n /// - Refer to the requirements in {withdraw}.\\n /// - Refer to the requirements in {IERC721.transferFrom}.\\n ///\\n /// @param streamId The ID of the stream NFT to transfer.\\n /// @param newRecipient The address of the new owner of the stream NFT.\\n /// @return withdrawnAmount The amount withdrawn, denoted in units of the asset's decimals.\\n function withdrawMaxAndTransfer(\\n uint256 streamId,\\n address newRecipient\\n ) external returns (uint128 withdrawnAmount);\\n\\n /// @notice Withdraws assets from streams to the recipient of each stream.\\n ///\\n /// @dev Emits multiple {Transfer}, {WithdrawFromLockupStream}, and {MetadataUpdate} events.\\n ///\\n /// Notes:\\n /// - This function attempts to call a hook on the recipient of each stream, unless `msg.sender` is the recipient.\\n ///\\n /// Requirements:\\n /// - Must not be delegate called.\\n /// - There must be an equal number of `streamIds` and `amounts`.\\n /// - Each stream ID in the array must not reference a null or depleted stream.\\n /// - Each amount in the array must be greater than zero and must not exceed the withdrawable amount.\\n ///\\n /// @param streamIds The IDs of the streams to withdraw from.\\n /// @param amounts The amounts to withdraw, denoted in units of the asset's decimals.\\n function withdrawMultiple(\\n uint256[] calldata streamIds,\\n uint128[] calldata amounts\\n ) external;\\n}\\n\",\"keccak256\":\"0x3e5541c38a901637bd310965deb5bbde73ef07fe4ee3c752cbec330c6b9d62a3\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/ISablierV2NFTDescriptor.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\n\\n/// @title ISablierV2NFTDescriptor\\n/// @notice This contract generates the URI describing the Sablier V2 stream NFTs.\\n/// @dev Inspired by Uniswap V3 Positions NFTs.\\ninterface ISablierV2NFTDescriptor {\\n /// @notice Produces the URI describing a particular stream NFT.\\n /// @dev This is a data URI with the JSON contents directly inlined.\\n /// @param sablier The address of the Sablier contract the stream was created in.\\n /// @param streamId The ID of the stream for which to produce a description.\\n /// @return uri The URI of the ERC721-compliant metadata.\\n function tokenURI(\\n IERC721Metadata sablier,\\n uint256 streamId\\n ) external view returns (string memory uri);\\n}\\n\",\"keccak256\":\"0x4ed430e553d14161e93efdaaacd1a502f49b38969c9d714b45d2e682a74fa0bc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/sablier/full/types/DataTypes.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\npragma solidity >=0.8.22;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {UD2x18} from \\\"@prb/math/src/UD2x18.sol\\\";\\nimport {UD60x18} from \\\"@prb/math/src/UD60x18.sol\\\";\\n\\n// DataTypes.sol\\n//\\n// This file defines all structs used in V2 Core, most of which are organized under three namespaces:\\n//\\n// - Lockup\\n// - LockupDynamic\\n// - LockupLinear\\n// - LockupTranched\\n//\\n// You will notice that some structs contain \\\"slot\\\" annotations - they are used to indicate the\\n// storage layout of the struct. It is more gas efficient to group small data types together so\\n// that they fit in a single 32-byte slot.\\n\\n/// @notice Struct encapsulating the broker parameters passed to the create functions. Both can be set to zero.\\n/// @param account The address receiving the broker's fee.\\n/// @param fee The broker's percentage fee from the total amount, denoted as a fixed-point number where 1e18 is 100%.\\nstruct Broker {\\n address account;\\n UD60x18 fee;\\n}\\n\\n/// @notice Namespace for the structs used in both {SablierV2LockupLinear} and {SablierV2LockupDynamic}.\\nlibrary Lockup {\\n /// @notice Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the asset's\\n /// decimals.\\n /// @dev Because the deposited and the withdrawn amount are often read together, declaring them in the same slot\\n /// saves gas.\\n /// @param deposited The initial amount deposited in the stream, net of broker fee.\\n /// @param withdrawn The cumulative amount withdrawn from the stream.\\n /// @param refunded The amount refunded to the sender. Unless the stream was canceled, this is always zero.\\n struct Amounts {\\n // slot 0\\n uint128 deposited;\\n uint128 withdrawn;\\n // slot 1\\n uint128 refunded;\\n }\\n\\n /// @notice Struct encapsulating (i) the deposit amount and (ii) the broker fee amount, both denoted in units of the\\n /// asset's decimals.\\n /// @param deposit The amount to deposit in the stream.\\n /// @param brokerFee The broker fee amount.\\n struct CreateAmounts {\\n uint128 deposit;\\n uint128 brokerFee;\\n }\\n\\n /// @notice Enum representing the different statuses of a stream.\\n /// @custom:value0 PENDING Stream created but not started; assets are in a pending state.\\n /// @custom:value1 STREAMING Active stream where assets are currently being streamed.\\n /// @custom:value2 SETTLED All assets have been streamed; recipient is due to withdraw them.\\n /// @custom:value3 CANCELED Canceled stream; remaining assets await recipient's withdrawal.\\n /// @custom:value4 DEPLETED Depleted stream; all assets have been withdrawn and/or refunded.\\n enum Status {\\n PENDING,\\n STREAMING,\\n SETTLED,\\n CANCELED,\\n DEPLETED\\n }\\n\\n /// @notice A common data structure to be stored in all {SablierV2Lockup} models.\\n /// @dev The fields are arranged like this to save gas via tight variable packing.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param endTime The Unix timestamp indicating the stream's end.\\n /// @param isCancelable Boolean indicating if the stream is cancelable.\\n /// @param wasCanceled Boolean indicating if the stream was canceled.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param isDepleted Boolean indicating if the stream is depleted.\\n /// @param isStream Boolean indicating if the struct entity exists.\\n /// @param isTransferable Boolean indicating if the stream NFT is transferable.\\n /// @param amounts Struct encapsulating the deposit, withdrawn, and refunded amounts, all denoted in units of the\\n /// asset's decimals.\\n struct Stream {\\n // slot 0\\n address sender;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n // slot 1\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n // slot 2 and 3\\n Lockup.Amounts amounts;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupDynamic}.\\nlibrary LockupDynamic {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param segments Segments with durations used to compose the dynamic distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n SegmentWithDuration[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupDynamic.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param segments Segments used to compose the dynamic distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Segment[] segments;\\n Broker broker;\\n }\\n\\n /// @notice Segment struct used in the Lockup Dynamic stream.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param timestamp The Unix timestamp indicating the segment's end.\\n struct Segment {\\n // slot 0\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 timestamp;\\n }\\n\\n /// @notice Segment struct used at runtime in {SablierV2LockupDynamic.createWithDurations}.\\n /// @param amount The amount of assets to be streamed in the segment, denoted in units of the asset's decimals.\\n /// @param exponent The exponent of the segment, denoted as a fixed-point number.\\n /// @param duration The time difference in seconds between the segment and the previous one.\\n struct SegmentWithDuration {\\n uint128 amount;\\n UD2x18 exponent;\\n uint40 duration;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the segments.\\n struct StreamLD {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Segment[] segments;\\n }\\n\\n /// @notice Struct encapsulating the LockupDynamic timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupLinear}.\\nlibrary LockupLinear {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param durations Struct encapsulating (i) cliff period duration and (ii) total stream duration, both in seconds.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Durations durations;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupLinear.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param timestamps Struct encapsulating (i) the stream's start time, (ii) cliff time, and (iii) end time, all as\\n /// Unix timestamps.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the cliff duration and the total duration.\\n /// @param cliff The cliff duration in seconds.\\n /// @param total The total duration in seconds.\\n struct Durations {\\n uint40 cliff;\\n uint40 total;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the cliff time.\\n struct StreamLL {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n uint40 endTime;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n uint40 cliffTime;\\n }\\n\\n /// @notice Struct encapsulating the LockupLinear timestamps.\\n /// @param start The Unix timestamp for the stream's start.\\n /// @param cliff The Unix timestamp for the cliff period's end. A value of zero means there is no cliff.\\n /// @param end The Unix timestamp for the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n}\\n\\n/// @notice Namespace for the structs used in {SablierV2LockupTranched}.\\nlibrary LockupTranched {\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithDurations} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param tranches Tranches with durations used to compose the tranched distribution function. Timestamps are\\n /// calculated by starting from `block.timestamp` and adding each duration to the previous timestamp.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithDurations {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n TrancheWithDuration[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the parameters of the {SablierV2LockupTranched.createWithTimestamps} function.\\n /// @param sender The address distributing the assets, with the ability to cancel the stream. It doesn't have to be\\n /// the same as `msg.sender`.\\n /// @param recipient The address receiving the assets.\\n /// @param totalAmount The total amount of ERC-20 assets to be distributed, including the stream deposit and any\\n /// broker fee, denoted in units of the asset's decimals.\\n /// @param asset The contract address of the ERC-20 asset to be distributed.\\n /// @param cancelable Indicates if the stream is cancelable.\\n /// @param transferable Indicates if the stream NFT is transferable.\\n /// @param startTime The Unix timestamp indicating the stream's start.\\n /// @param tranches Tranches used to compose the tranched distribution function.\\n /// @param broker Struct encapsulating (i) the address of the broker assisting in creating the stream, and (ii) the\\n /// percentage fee paid to the broker from `totalAmount`, denoted as a fixed-point number. Both can be set to zero.\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n uint40 startTime;\\n Tranche[] tranches;\\n Broker broker;\\n }\\n\\n /// @notice Struct encapsulating the full details of a stream.\\n /// @dev Extends `Lockup.Stream` by including the recipient and the tranches.\\n struct StreamLT {\\n address sender;\\n address recipient;\\n uint40 startTime;\\n uint40 endTime;\\n bool isCancelable;\\n bool wasCanceled;\\n IERC20 asset;\\n bool isDepleted;\\n bool isStream;\\n bool isTransferable;\\n Lockup.Amounts amounts;\\n Tranche[] tranches;\\n }\\n\\n /// @notice Struct encapsulating the LockupTranched timestamps.\\n /// @param start The Unix timestamp indicating the stream's start.\\n /// @param end The Unix timestamp indicating the stream's end.\\n struct Timestamps {\\n uint40 start;\\n uint40 end;\\n }\\n\\n /// @notice Tranche struct used in the Lockup Tranched stream.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param timestamp The Unix timestamp indicating the tranche's end.\\n struct Tranche {\\n // slot 0\\n uint128 amount;\\n uint40 timestamp;\\n }\\n\\n /// @notice Tranche struct used at runtime in {SablierV2LockupTranched.createWithDurations}.\\n /// @param amount The amount of assets to be unlocked in the tranche, denoted in units of the asset's decimals.\\n /// @param duration The time difference in seconds between the tranche and the previous one.\\n struct TrancheWithDuration {\\n uint128 amount;\\n uint40 duration;\\n }\\n}\\n\",\"keccak256\":\"0x727722c0ec71a76a947b935c9dfcac8fd846d6c3547dfbc8739c7109f3b95068\",\"license\":\"GPL-3.0-or-later\"}},\"version\":1}", - "bytecode": "0x6080604052348015600f57600080fd5b506105fe8061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636778d4b0146100465780637dc14a8e1461005b578063a3f4df7e1461006e575b600080fd5b6100596100543660046103d0565b6100c0565b005b610059610069366004610423565b610256565b6100aa6040518060400160405280601d81526020017f446563656e745361626c69657253747265616d4d616e6167656d656e7400000081525081565b6040516100b79190610495565b60405180910390f35b60405163d975dfed60e01b8152600481018390526000906001600160a01b0386169063d975dfed90602401602060405180830381865afa158015610108573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061012c91906104af565b9050806001600160801b03166000036101455750610250565b336001600160a01b031663468721a7856000886000888860405160240161017f9291909182526001600160a01b0316602082015260400190565b60408051601f198184030181529181526020820180516001600160e01b031663ea5ead1960e01b179052516101bc939291906000906024016104d8565b60408051601f198184030181529181526020820180516001600160e01b0316635194544760e01b1790525160e085901b6001600160e01b031916815261020a9392919060009060040161052f565b6020604051808303816000875af1158015610229573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061024d9190610585565b50505b50505050565b604051632b4d7bf560e21b8152600481018290526000906001600160a01b0384169063ad35efd490602401602060405180830381865afa15801561029e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102c291906105a7565b905060008160048111156102d8576102d8610519565b141580156102f8575060018160048111156102f5576102f5610519565b14155b1561030257505050565b336001600160a01b031663468721a78460008560405160240161032791815260200190565b60408051601f198184030181529181526020820180516001600160e01b03166340e58ee560e01b1790525160e085901b6001600160e01b03191681526103759392919060009060040161052f565b6020604051808303816000875af1158015610394573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102509190610585565b6001600160a01b03811681146103cd57600080fd5b50565b600080600080608085870312156103e657600080fd5b84356103f1816103b8565b93506020850135610401816103b8565b9250604085013591506060850135610418816103b8565b939692955090935050565b6000806040838503121561043657600080fd5b8235610441816103b8565b946020939093013593505050565b6000815180845260005b8181101561047557602081850181015186830182015201610459565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006104a8602083018461044f565b9392505050565b6000602082840312156104c157600080fd5b81516001600160801b03811681146104a857600080fd5b6001600160a01b038516815260ff841660208201526080604082018190526000906105059083018561044f565b905060ff8316606083015295945050505050565b634e487b7160e01b600052602160045260246000fd5b60018060a01b0385168152836020820152608060408201526000610556608083018561044f565b90506002831061057657634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b60006020828403121561059757600080fd5b815180151581146104a857600080fd5b6000602082840312156105b957600080fd5b8151600581106104a857600080fdfea2646970667358221220c473750d62fe01ec9f421a499df8738e767b4a5341626c81a992fcdb3ee192de64736f6c634300081c0033", - "devdoc": { - "kind": "dev", - "methods": {}, - "version": 1 - }, - "userdoc": { - "kind": "user", - "methods": {}, - "version": 1 - }, - "storageLayout": { - "storage": [], - "types": null - } -} \ No newline at end of file From 2af0ffdd1df2bddf03bf1ab5a5c743706da71e6e Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 16:37:31 -0400 Subject: [PATCH 189/206] Add version to DecentAutonomousAdmin contract name, move into own directory --- .../DecentAutonomousAdminV1.sol} | 19 +++++++++---------- .../IDecentAutonomousAdminV1.sol} | 4 ++-- .../DecentAutonomousAdminV1.test.ts} | 14 +++++++------- test/modules/DecentHatsCreationModule.test.ts | 10 ++++++---- .../DecentHatsModificationModule.test.ts | 8 ++++---- .../DecentSablierStreamManagement.test.ts | 8 ++++---- 6 files changed, 32 insertions(+), 31 deletions(-) rename contracts/{DecentAutonomousAdmin.sol => autonomous-admin/DecentAutonomousAdminV1.sol} (73%) rename contracts/interfaces/{IDecentAutonomousAdmin.sol => autonomous-admin/IDecentAutonomousAdminV1.sol} (80%) rename test/{DecentAutonomousAdmin.test.ts => autonomous-admin/DecentAutonomousAdminV1.test.ts} (93%) diff --git a/contracts/DecentAutonomousAdmin.sol b/contracts/autonomous-admin/DecentAutonomousAdminV1.sol similarity index 73% rename from contracts/DecentAutonomousAdmin.sol rename to contracts/autonomous-admin/DecentAutonomousAdminV1.sol index b37d1ec2..2c752392 100644 --- a/contracts/DecentAutonomousAdmin.sol +++ b/contracts/autonomous-admin/DecentAutonomousAdminV1.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IHats} from "./interfaces/hats/IHats.sol"; -import {IHatsElectionsEligibility} from "./interfaces/hats/modules/IHatsElectionsEligibility.sol"; +import {IHats} from "../interfaces/hats/IHats.sol"; +import {IHatsElectionsEligibility} from "../interfaces/hats/modules/IHatsElectionsEligibility.sol"; import {FactoryFriendly} from "@gnosis.pm/zodiac/contracts/factory/FactoryFriendly.sol"; import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; -import {IDecentAutonomousAdmin} from "./interfaces/IDecentAutonomousAdmin.sol"; +import {IDecentAutonomousAdminV1} from "../interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol"; -contract DecentAutonomousAdmin is - IDecentAutonomousAdmin, +contract DecentAutonomousAdminV1 is + IDecentAutonomousAdminV1, ERC165, FactoryFriendly { @@ -21,10 +21,9 @@ contract DecentAutonomousAdmin is // Public Functions // ////////////////////////////////////////////////////////////// function triggerStartNextTerm(TriggerStartArgs calldata args) public { - if ( - args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId) == - false - ) revert NotCurrentWearer(); + if (!args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId)) { + revert NotCurrentWearer(); + } IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility( args.hatsProtocol.getHatEligibilityModule(args.hatId) @@ -42,7 +41,7 @@ contract DecentAutonomousAdmin is bytes4 interfaceId ) public view override returns (bool) { return - interfaceId == type(IDecentAutonomousAdmin).interfaceId || + interfaceId == type(IDecentAutonomousAdminV1).interfaceId || super.supportsInterface(interfaceId); } } diff --git a/contracts/interfaces/IDecentAutonomousAdmin.sol b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol similarity index 80% rename from contracts/interfaces/IDecentAutonomousAdmin.sol rename to contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol index 42656801..bbac8b0d 100644 --- a/contracts/interfaces/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IHats} from "./hats/IHats.sol"; +import {IHats} from "../hats/IHats.sol"; -interface IDecentAutonomousAdmin { +interface IDecentAutonomousAdminV1 { error NotCurrentWearer(); struct TriggerStartArgs { address currentWearer; diff --git a/test/DecentAutonomousAdmin.test.ts b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts similarity index 93% rename from test/DecentAutonomousAdmin.test.ts rename to test/autonomous-admin/DecentAutonomousAdminV1.test.ts index 1a1b965e..89bd8d3d 100644 --- a/test/DecentAutonomousAdmin.test.ts +++ b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts @@ -2,16 +2,16 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { expect } from 'chai'; import hre from 'hardhat'; import { - DecentAutonomousAdmin, - DecentAutonomousAdmin__factory, + DecentAutonomousAdminV1, + DecentAutonomousAdminV1__factory, MockHats, MockHats__factory, MockHatsElectionsEligibility, MockHatsElectionsEligibility__factory, -} from '../typechain-types'; -import { topHatIdToHatId } from './helpers'; +} from '../../typechain-types'; +import { topHatIdToHatId } from '../helpers'; -describe('DecentAutonomousAdminHat', function () { +describe('DecentAutonomousAdminHatV1', function () { // Signer accounts let deployer: SignerWithAddress; let currentWearer: SignerWithAddress; @@ -21,7 +21,7 @@ describe('DecentAutonomousAdminHat', function () { // Contract instances let hatsProtocol: MockHats; let hatsElectionModule: MockHatsElectionsEligibility; - let decentAutonomousAdminInstance: DecentAutonomousAdmin; + let decentAutonomousAdminInstance: DecentAutonomousAdminV1; // Variables let userHatId: bigint; @@ -53,7 +53,7 @@ describe('DecentAutonomousAdminHat', function () { ); // Deploy DecentAutonomousAdminHat contract with the admin hat ID - decentAutonomousAdminInstance = await new DecentAutonomousAdmin__factory(deployer).deploy(); + decentAutonomousAdminInstance = await new DecentAutonomousAdminV1__factory(deployer).deploy(); const adminHatAddress = await decentAutonomousAdminInstance.getAddress(); // Mint the admin hat to adminHatWearer await hatsProtocol.mintHat(adminHatId, adminHatAddress); diff --git a/test/modules/DecentHatsCreationModule.test.ts b/test/modules/DecentHatsCreationModule.test.ts index 2d3d7025..dfd6eeae 100644 --- a/test/modules/DecentHatsCreationModule.test.ts +++ b/test/modules/DecentHatsCreationModule.test.ts @@ -21,8 +21,8 @@ import { MockSablierV2LockupLinear, MockERC20__factory, MockERC20, - DecentAutonomousAdmin, - DecentAutonomousAdmin__factory, + DecentAutonomousAdminV1, + DecentAutonomousAdminV1__factory, MockHatsElectionsEligibility__factory, MockHatsModuleFactory__factory, ModuleProxyFactory, @@ -65,7 +65,7 @@ describe('DecentHatsCreationModule', () => { let mockHatsModuleFactoryAddress: string; let moduleProxyFactory: ModuleProxyFactory; - let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; + let decentAutonomousAdminMasterCopy: DecentAutonomousAdminV1; beforeEach(async () => { try { const signers = await hre.ethers.getSigners(); @@ -90,7 +90,9 @@ describe('DecentHatsCreationModule', () => { decentHatsCreationModule = await new DecentHatsCreationModule__factory(deployer).deploy(); decentHatsCreationModuleAddress = await decentHatsCreationModule.getAddress(); moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); - decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdminV1__factory( + deployer, + ).deploy(); const gnosisSafeProxyFactory = getGnosisSafeProxyFactory(); const gnosisSafeL2Singleton = getGnosisSafeL2Singleton(); diff --git a/test/modules/DecentHatsModificationModule.test.ts b/test/modules/DecentHatsModificationModule.test.ts index f601300e..7ad920ec 100644 --- a/test/modules/DecentHatsModificationModule.test.ts +++ b/test/modules/DecentHatsModificationModule.test.ts @@ -22,9 +22,9 @@ import { MockERC20__factory, MockERC20, ModuleProxyFactory, - DecentAutonomousAdmin, ModuleProxyFactory__factory, - DecentAutonomousAdmin__factory, + DecentAutonomousAdminV1, + DecentAutonomousAdminV1__factory, MockHatsModuleFactory__factory, MockHatsElectionsEligibility__factory, DecentHatsCreationModule, @@ -69,7 +69,7 @@ describe('DecentHatsModificationModule', () => { let mockHatsModuleFactoryAddress: string; let moduleProxyFactory: ModuleProxyFactory; - let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; + let decentAutonomousAdminMasterCopy: DecentAutonomousAdminV1; beforeEach(async () => { const signers = await hre.ethers.getSigners(); @@ -89,7 +89,7 @@ describe('DecentHatsModificationModule', () => { ).deploy(); decentHatsModificationModuleAddress = await decentHatsModificationModule.getAddress(); moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); - decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdminV1__factory(deployer).deploy(); const mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); mockHatsModuleFactoryAddress = await mockHatsModuleFactory.getAddress(); diff --git a/test/modules/DecentSablierStreamManagement.test.ts b/test/modules/DecentSablierStreamManagement.test.ts index 4ad59aa0..99a20881 100644 --- a/test/modules/DecentSablierStreamManagement.test.ts +++ b/test/modules/DecentSablierStreamManagement.test.ts @@ -4,8 +4,8 @@ import { expect } from 'chai'; import { ethers } from 'ethers'; import hre from 'hardhat'; import { - DecentAutonomousAdmin, - DecentAutonomousAdmin__factory, + DecentAutonomousAdminV1, + DecentAutonomousAdminV1__factory, DecentHatsCreationModule, DecentHatsCreationModule__factory, DecentSablierStreamManagementModule, @@ -76,7 +76,7 @@ describe('DecentSablierStreamManagement', () => { let roleHatId: bigint; let mockHatsModuleFactory: MockHatsModuleFactory; let moduleProxyFactory: ModuleProxyFactory; - let decentAutonomousAdminMasterCopy: DecentAutonomousAdmin; + let decentAutonomousAdminMasterCopy: DecentAutonomousAdminV1; let hatsElectionsEligibilityImplementation: MockHatsElectionsEligibility; beforeEach(async () => { @@ -97,7 +97,7 @@ describe('DecentSablierStreamManagement', () => { mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); - decentAutonomousAdminMasterCopy = await new DecentAutonomousAdmin__factory(deployer).deploy(); + decentAutonomousAdminMasterCopy = await new DecentAutonomousAdminV1__factory(deployer).deploy(); hatsElectionsEligibilityImplementation = await new MockHatsElectionsEligibility__factory( deployer, ).deploy(); From c16fdbc5a914acee3c0eba4a94385141dff6a6ee Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 17:22:01 -0400 Subject: [PATCH 190/206] Add some more time helpers --- test/time.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/time.ts b/test/time.ts index 6c520709..e5dd6060 100644 --- a/test/time.ts +++ b/test/time.ts @@ -10,6 +10,16 @@ const advanceBlocks = async (blockCount: number) => { } }; +export const setTime = async (time: number) => { + await hre.ethers.provider.send('evm_setNextBlockTimestamp', [time]); + await hre.ethers.provider.send('evm_mine', []); +}; + +export const currentBlockTimestamp = async () => { + return (await hre.ethers.provider.getBlock(await hre.ethers.provider.getBlockNumber()))! + .timestamp; +}; + const defaultExport = { advanceBlocks, advanceBlock, From 27932916c2c93db8a414677954396a72c03328ce Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 17:22:18 -0400 Subject: [PATCH 191/206] Beef up the Mock Hats Elections Eligibility contract --- .../mocks/MockHatsElectionEligibility.sol | 142 +++++++++++++++--- 1 file changed, 123 insertions(+), 19 deletions(-) diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionEligibility.sol index baea0999..d088ccb2 100644 --- a/contracts/mocks/MockHatsElectionEligibility.sol +++ b/contracts/mocks/MockHatsElectionEligibility.sol @@ -3,35 +3,139 @@ pragma solidity ^0.8.19; import {IHatsElectionsEligibility} from "../interfaces/hats/modules/IHatsElectionsEligibility.sol"; contract MockHatsElectionsEligibility is IHatsElectionsEligibility { - function currentTermEnd() external view returns (uint128) {} + // Storage + mapping(uint128 termEnd => mapping(address candidates => bool elected)) + public electionResults; + mapping(uint128 termEnd => bool isElectionOpen) public electionStatus; + uint128 public currentTermEnd; + uint128 public nextTermEnd; - function nextTermEnd() external view returns (uint128) {} + // Errors + error AlreadySetup(); + error ElectionNotOpen(); + error InvalidTermEnd(); + error NoActiveElection(); + error ElectionClosed(uint128 termEnd); + error TermNotEnded(); + error NextTermNotReady(); + error TooManyWinners(); - function electionStatus( - uint128 termEnd - ) external view returns (bool isElectionOpen) {} + modifier onlyOnce() { + if (currentTermEnd != 0) revert AlreadySetup(); + _; + } + + // Can only be called once by the constructor + function setup( + uint128 _firstTermEnd, + address[] calldata _winners + ) external onlyOnce { + require( + _firstTermEnd > block.timestamp, + "First term must be in the future" + ); + currentTermEnd = _firstTermEnd; + for (uint256 i; i < _winners.length; ) { + electionResults[_firstTermEnd][_winners[i]] = true; - function electionResults( - uint128 termEnd, - address candidate - ) external view returns (bool elected) {} + unchecked { + ++i; + } + } + } - function BALLOT_BOX_HAT() external pure returns (uint256) {} + function elect(uint128 _termEnd, address[] calldata _winners) external { + // results can only be submitted for open elections + if (!electionStatus[_termEnd]) revert ElectionClosed(_termEnd); - function ADMIN_HAT() external pure returns (uint256) {} + // close the election + electionStatus[_termEnd] = false; - function elect(uint128 _termEnd, address[] calldata _winners) external {} + // set the election results + for (uint256 i; i < _winners.length; ) { + electionResults[_termEnd][_winners[i]] = true; - function recall(uint128 _termEnd, address[] calldata _recallees) external {} + unchecked { + ++i; + } + } - function setNextTerm(uint128 _newTermEnd) external {} + // log the election results + emit ElectionCompleted(_termEnd, _winners); + } - function startNextTerm() external {} + function recall(uint128 _termEnd, address[] calldata _recallees) external { + // loop through the accounts and set their election status to false + for (uint256 i; i < _recallees.length; ) { + electionResults[_termEnd][_recallees[i]] = false; + + unchecked { + ++i; + } + } + + emit Recalled(_termEnd, _recallees); + } + + function setNextTerm(uint128 _newTermEnd) external { + // new term must end after current term + if (_newTermEnd <= currentTermEnd) revert InvalidTermEnd(); + + // if next term is already set, its election must still be open + uint128 next = nextTermEnd; + if (next > 0 && !electionStatus[next]) revert ElectionClosed(next); + + // set the next term + nextTermEnd = _newTermEnd; + + // open the next election + electionStatus[_newTermEnd] = true; + + // log the new term + emit ElectionOpened(_newTermEnd); + } + + function startNextTerm() external { + // current term must be over + if (block.timestamp < currentTermEnd) revert TermNotEnded(); + + uint128 next = nextTermEnd; // save SLOADs + + // next term must be set and its election must be closed + if (next == 0 || electionStatus[next]) revert NextTermNotReady(); + + // set the current term to the next term + currentTermEnd = next; + + // clear the next term + nextTermEnd = 0; + + // log the change + emit NewTermStarted(next); + } function getWearerStatus( - address, - uint256 - ) external pure returns (bool eligible, bool standing) { - return (true, true); + address _wearer, + uint256 /* _hatId */ + ) public view override returns (bool eligible, bool standing) { + /// @dev This eligibility module is not concerned with standing, so we default it to good standing + standing = true; + + uint128 current = currentTermEnd; // save SLOAD + + if (block.timestamp < current) { + // if the current term is still open, the wearer is eligible if they have been elected for the current term + eligible = electionResults[current][_wearer]; + } + // if the current term is closed, the wearer is not eligible } + + // // Test helper functions + // function setWearerStatus(address wearer, bool eligible) external { + // electionResults[currentTermEnd][wearer] = eligible; + // } + + function BALLOT_BOX_HAT() external pure override returns (uint256) {} + + function ADMIN_HAT() external pure override returns (uint256) {} } From 76a4387f1eea7818628ca9d13a92918ece5e5ada Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 17:22:35 -0400 Subject: [PATCH 192/206] Fix a bug in the Decent Autonomous Admin contract --- .../DecentAutonomousAdminV1.sol | 4 - .../DecentAutonomousAdminV1.test.ts | 116 +++++++++++------- 2 files changed, 71 insertions(+), 49 deletions(-) diff --git a/contracts/autonomous-admin/DecentAutonomousAdminV1.sol b/contracts/autonomous-admin/DecentAutonomousAdminV1.sol index 2c752392..3588fc29 100644 --- a/contracts/autonomous-admin/DecentAutonomousAdminV1.sol +++ b/contracts/autonomous-admin/DecentAutonomousAdminV1.sol @@ -21,10 +21,6 @@ contract DecentAutonomousAdminV1 is // Public Functions // ////////////////////////////////////////////////////////////// function triggerStartNextTerm(TriggerStartArgs calldata args) public { - if (!args.hatsProtocol.isWearerOfHat(args.currentWearer, args.hatId)) { - revert NotCurrentWearer(); - } - IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility( args.hatsProtocol.getHatEligibilityModule(args.hatId) ); diff --git a/test/autonomous-admin/DecentAutonomousAdminV1.test.ts b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts index 89bd8d3d..07bcccb7 100644 --- a/test/autonomous-admin/DecentAutonomousAdminV1.test.ts +++ b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts @@ -10,13 +10,14 @@ import { MockHatsElectionsEligibility__factory, } from '../../typechain-types'; import { topHatIdToHatId } from '../helpers'; +import { currentBlockTimestamp, setTime } from '../time'; describe('DecentAutonomousAdminHatV1', function () { // Signer accounts let deployer: SignerWithAddress; - let currentWearer: SignerWithAddress; + let firstWearer: SignerWithAddress; let randomUser: SignerWithAddress; - let nominatedWearer: SignerWithAddress; + let secondWearer: SignerWithAddress; // Contract instances let hatsProtocol: MockHats; @@ -24,24 +25,24 @@ describe('DecentAutonomousAdminHatV1', function () { let decentAutonomousAdminInstance: DecentAutonomousAdminV1; // Variables - let userHatId: bigint; + let roleHatId: bigint; + + let firstTermEnd: number; + let nextTermEnd: number; beforeEach(async function () { // Get signers - [deployer, currentWearer, nominatedWearer, randomUser] = await hre.ethers.getSigners(); + [deployer, firstWearer, secondWearer, randomUser] = await hre.ethers.getSigners(); // Deploy MockHatsAutoAdmin (Mock Hats Protocol) hatsProtocol = await new MockHats__factory(deployer).deploy(); - // Deploy MockHatsElectionEligibility (Eligibility Module) - hatsElectionModule = await new MockHatsElectionsEligibility__factory(deployer).deploy(); - + // Create Top Hat, mint to deployer const topHatId = topHatIdToHatId((await hatsProtocol.lastTopHatId()) + 1n); await hatsProtocol.mintTopHat(deployer.address, 'Details', 'imageURI'); - const adminHatId = await hatsProtocol.getNextId(topHatId); - // Create Admin Hat + const adminHatId = await hatsProtocol.getNextId(topHatId); await hatsProtocol.createHat( topHatId, // top hat id 'Details', // Hat details @@ -52,59 +53,84 @@ describe('DecentAutonomousAdminHatV1', function () { 'imageURI', // Image URI ); - // Deploy DecentAutonomousAdminHat contract with the admin hat ID + // Deploy DecentAutonomousAdminHat contract decentAutonomousAdminInstance = await new DecentAutonomousAdminV1__factory(deployer).deploy(); - const adminHatAddress = await decentAutonomousAdminInstance.getAddress(); - // Mint the admin hat to adminHatWearer - await hatsProtocol.mintHat(adminHatId, adminHatAddress); + const autonomousAdminAddress = await decentAutonomousAdminInstance.getAddress(); + + // Mint the admin hat to autonomous admin contract + await hatsProtocol.mintHat(adminHatId, autonomousAdminAddress); + + // Deploy MockHatsElectionEligibility (Eligibility Module) + hatsElectionModule = await new MockHatsElectionsEligibility__factory(deployer).deploy(); + + // setup the first term - userHatId = await hatsProtocol.getNextId(adminHatId); + firstTermEnd = (await currentBlockTimestamp()) + 100; + await hatsElectionModule.setup(firstTermEnd, [await firstWearer.getAddress()]); // Create User Hat under the admin hat + roleHatId = await hatsProtocol.getNextId(adminHatId); await hatsProtocol.createHat( adminHatId, // Admin hat id 'Details', // Hat details - 100, // Max supply + 1, // Max supply await hatsElectionModule.getAddress(), // Eligibility module (election module) '0x0000000000000000000000000000000000004a75', // Toggle module (none) false, // Is mutable 'imageURI', // Image URI ); - // Mint the user hat to currentWearer - await hatsProtocol.mintHat(userHatId, await currentWearer.getAddress()); + // Mint the role hat to currentWearer + await hatsProtocol.mintHat(roleHatId, await firstWearer.getAddress()); + + // set up the next election + nextTermEnd = firstTermEnd + 100; + await hatsElectionModule.setNextTerm(nextTermEnd); + await hatsElectionModule.elect(nextTermEnd, [await secondWearer.getAddress()]); }); describe('triggerStartNextTerm', function () { - it('should correctly validate current wearer and transfer', async function () { - const args = { - currentWearer: await currentWearer.getAddress(), - hatsProtocol: await hatsProtocol.getAddress(), - hatId: userHatId, - nominatedWearer: nominatedWearer.address, - }; - - // Call triggerStartNextTerm on the decentAutonomousAdminInstance contract - await decentAutonomousAdminInstance.triggerStartNextTerm(args); - - // Verify the hat is now worn by the nominated wearer - expect((await hatsProtocol.isWearerOfHat(nominatedWearer.address, userHatId)) === true); - - expect((await hatsProtocol.isWearerOfHat(currentWearer.address, userHatId)) === false); + describe('before the first term is over', function () { + it('should have correct wearers', async () => { + expect(await hatsProtocol.isWearerOfHat(firstWearer.address, roleHatId)).to.equal(true); + expect(await hatsProtocol.isWearerOfHat(secondWearer.address, roleHatId)).to.equal(false); + }); }); - it('should correctly invalidate random address as current wearer', async function () { - const args = { - currentWearer: randomUser.address, - hatsProtocol: await hatsProtocol.getAddress(), - hatId: userHatId, - nominatedWearer: nominatedWearer.address, - sablierStreamInfo: [], // No Sablier stream info for this test - }; - - // revert if not the current wearer - await expect( - decentAutonomousAdminInstance.connect(randomUser).triggerStartNextTerm(args), - ).to.be.revertedWithCustomError(decentAutonomousAdminInstance, 'NotCurrentWearer'); + + describe('after the first term is over', function () { + beforeEach(async () => { + // Wait until the first term is over + await setTime(firstTermEnd + 1); + }); + + describe('with a valid current wearer', function () { + beforeEach(async () => { + await decentAutonomousAdminInstance.triggerStartNextTerm({ + currentWearer: await firstWearer.getAddress(), + nominatedWearer: secondWearer.address, + hatsProtocol: await hatsProtocol.getAddress(), + hatId: roleHatId, + }); + }); + + it('should have correct wearers after triggering next term', async () => { + expect(await hatsProtocol.isWearerOfHat(firstWearer.address, roleHatId)).to.equal(false); + expect(await hatsProtocol.isWearerOfHat(secondWearer.address, roleHatId)).to.equal(true); + }); + }); + + describe('with invalid current wearer', function () { + it('should revert if the current wearer is not the wearer of the hat', async () => { + await expect( + decentAutonomousAdminInstance.triggerStartNextTerm({ + currentWearer: await randomUser.getAddress(), + nominatedWearer: secondWearer.address, + hatsProtocol: await hatsProtocol.getAddress(), + hatId: roleHatId, + }), + ).to.be.revertedWithCustomError(hatsProtocol, 'AllHatsWorn'); + }); + }); }); }); }); From 169f387cde2d8f125445e2a5989af178096653c9 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 17:56:27 -0400 Subject: [PATCH 193/206] Inline a thing --- .../modules/DecentHatsCreationModule.sol | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/contracts/modules/DecentHatsCreationModule.sol b/contracts/modules/DecentHatsCreationModule.sol index ee4319f6..e15aa3da 100644 --- a/contracts/modules/DecentHatsCreationModule.sol +++ b/contracts/modules/DecentHatsCreationModule.sol @@ -84,19 +84,20 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { ); // Create Role Hats - CreateRoleHatsParams memory roleHatParams = CreateRoleHatsParams({ - hatsProtocol: params.hatsProtocol, - erc6551Registry: params.erc6551Registry, - hatsAccountImplementation: params.hatsAccountImplementation, - topHatId: topHatId, - topHatAccount: topHatAccount, - hatsModuleFactory: params.hatsModuleFactory, - hatsElectionsEligibilityImplementation: params - .hatsElectionsEligibilityImplementation, - adminHatId: adminHatId, - hats: params.hats - }); - _processRoleHats(roleHatParams); + _processRoleHats( + CreateRoleHatsParams({ + hatsProtocol: params.hatsProtocol, + erc6551Registry: params.erc6551Registry, + hatsAccountImplementation: params.hatsAccountImplementation, + topHatId: topHatId, + topHatAccount: topHatAccount, + hatsModuleFactory: params.hatsModuleFactory, + hatsElectionsEligibilityImplementation: params + .hatsElectionsEligibilityImplementation, + adminHatId: adminHatId, + hats: params.hats + }) + ); } /* ///////////////////////////////////////////////////////////////////////////// From 324b773b1db9581e89d4583a2f42b05caaf1824a Mon Sep 17 00:00:00 2001 From: David Colon <38386583+Da-Colon@users.noreply.github.com> Date: Thu, 31 Oct 2024 20:19:28 -0400 Subject: [PATCH 194/206] add expected `_setUp` function to electionModule and call it in mock factory --- contracts/mocks/MockHatsElectionEligibility.sol | 14 ++++++++++++++ contracts/mocks/MockHatsModuleFactory.sol | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionEligibility.sol index d088ccb2..74c05783 100644 --- a/contracts/mocks/MockHatsElectionEligibility.sol +++ b/contracts/mocks/MockHatsElectionEligibility.sol @@ -44,6 +44,20 @@ contract MockHatsElectionsEligibility is IHatsElectionsEligibility { } } + function _setUp(bytes calldata _initData) external onlyOnce { + // decode init data + uint128 firstTermEnd = abi.decode(_initData, (uint128)); + + // set currentTermEnd + currentTermEnd = firstTermEnd; + + // open the first election + electionStatus[firstTermEnd] = true; + + // log the first term + emit ElectionOpened(firstTermEnd); + } + function elect(uint128 _termEnd, address[] calldata _winners) external { // results can only be submitted for open elections if (!electionStatus[_termEnd]) revert ElectionClosed(_termEnd); diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol index 3f12ddba..accf4cb2 100644 --- a/contracts/mocks/MockHatsModuleFactory.sol +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -9,11 +9,12 @@ contract MockHatsModuleFactory is IHatsModuleFactory { address, uint256, bytes calldata, - bytes calldata, + bytes calldata _initData, uint256 ) external override returns (address _instance) { // Deploy a new instance of MockHatsElectionEligibility MockHatsElectionsEligibility newModule = new MockHatsElectionsEligibility(); + newModule._setUp(_initData); _instance = address(newModule); } From 8581d899afd0b84a427d7c625debc6f8eb022a63 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 22:17:55 -0400 Subject: [PATCH 195/206] Add some comments to contract --- contracts/modules/DecentHatsModuleUtils.sol | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contracts/modules/DecentHatsModuleUtils.sol b/contracts/modules/DecentHatsModuleUtils.sol index 09720a76..f241208b 100644 --- a/contracts/modules/DecentHatsModuleUtils.sol +++ b/contracts/modules/DecentHatsModuleUtils.sol @@ -104,6 +104,7 @@ abstract contract DecentHatsModuleUtils { uint256 adminHatId, uint128 termEndDateTs ) private returns (address) { + // If the Hat is termed, create the eligibility module if (termEndDateTs != 0) { return hatsModuleFactory.createHatsModule( @@ -114,6 +115,8 @@ abstract contract DecentHatsModuleUtils { uint256(SALT) ); } + + // Otherwise, return the Top Hat account return topHatAccount; } @@ -124,7 +127,10 @@ abstract contract DecentHatsModuleUtils { address eligibilityAddress, address topHatAccount ) private returns (uint256) { + // Grab the next Hat ID (before creating it) uint256 hatId = hatsProtocol.getNextId(adminHatId); + + // Create the new Hat IAvatar(msg.sender).execTransactionFromModule( address(hatsProtocol), 0, @@ -141,7 +147,7 @@ abstract contract DecentHatsModuleUtils { Enum.Operation.Call ); - // If the hat is termed, nominate the wearer as the eligible member + // If the Hat is termed, nominate the wearer as the eligible member if (hat.termEndDateTs != 0) { address[] memory nominatedWearers = new address[](1); nominatedWearers[0] = hat.wearer; @@ -158,6 +164,7 @@ abstract contract DecentHatsModuleUtils { ); } + // Mint the Hat IAvatar(msg.sender).execTransactionFromModule( address(hatsProtocol), 0, From 8ab6feda22c6feff4821366988a302d080f0786f Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 22:24:41 -0400 Subject: [PATCH 196/206] More contract cleanup --- .../modules/DecentHatsCreationModule.sol | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/contracts/modules/DecentHatsCreationModule.sol b/contracts/modules/DecentHatsCreationModule.sol index e15aa3da..5df50a43 100644 --- a/contracts/modules/DecentHatsCreationModule.sol +++ b/contracts/modules/DecentHatsCreationModule.sol @@ -60,42 +60,46 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. * We also make use of `KeyValuePairs` to associate the topHatId with the Safe. + * + * @param treeParams The parameters for creating the Hat Tree with Roles */ - function createAndDeclareTree(CreateTreeParams calldata params) external { + function createAndDeclareTree( + CreateTreeParams calldata treeParams + ) external { // Create Top Hat (uint256 topHatId, address topHatAccount) = _processTopHat( - params.hatsProtocol, - params.erc6551Registry, - params.hatsAccountImplementation, - params.keyValuePairs, - params.topHat + treeParams.hatsProtocol, + treeParams.erc6551Registry, + treeParams.hatsAccountImplementation, + treeParams.keyValuePairs, + treeParams.topHat ); // Create Admin Hat uint256 adminHatId = _processAdminHat( - params.hatsProtocol, - params.erc6551Registry, - params.hatsAccountImplementation, + treeParams.hatsProtocol, + treeParams.erc6551Registry, + treeParams.hatsAccountImplementation, topHatId, topHatAccount, - params.moduleProxyFactory, - params.decentAutonomousAdminImplementation, - params.adminHat + treeParams.moduleProxyFactory, + treeParams.decentAutonomousAdminImplementation, + treeParams.adminHat ); // Create Role Hats _processRoleHats( CreateRoleHatsParams({ - hatsProtocol: params.hatsProtocol, - erc6551Registry: params.erc6551Registry, - hatsAccountImplementation: params.hatsAccountImplementation, + hatsProtocol: treeParams.hatsProtocol, + erc6551Registry: treeParams.erc6551Registry, + hatsAccountImplementation: treeParams.hatsAccountImplementation, topHatId: topHatId, topHatAccount: topHatAccount, - hatsModuleFactory: params.hatsModuleFactory, - hatsElectionsEligibilityImplementation: params + hatsModuleFactory: treeParams.hatsModuleFactory, + hatsElectionsEligibilityImplementation: treeParams .hatsElectionsEligibilityImplementation, adminHatId: adminHatId, - hats: params.hats + hats: treeParams.hats }) ); } @@ -109,7 +113,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { IERC6551Registry erc6551Registry, address hatsAccountImplementation, address keyValuePairs, - TopHatParams memory topHat + TopHatParams calldata topHat ) internal returns (uint256 topHatId, address topHatAccount) { // Call lastTopHatId() and properly decode the response (bool success, bytes memory data) = address(hatsProtocol).call( @@ -118,8 +122,8 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { require(success, "Failed to get lastTopHatId"); topHatId = (abi.decode(data, (uint256)) + 1) << 224; + // Mint Top Hat to the Safe IAvatar(msg.sender).execTransactionFromModule( - // Mint top hat to the safe address(hatsProtocol), 0, abi.encodeWithSignature( @@ -131,7 +135,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { Enum.Operation.Call ); - // Create top hat account + // Create Top Hat's ERC6551 Account topHatAccount = erc6551Registry.createAccount( hatsAccountImplementation, SALT, @@ -165,7 +169,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { address topHatAccount, ModuleProxyFactory moduleProxyFactory, address decentAutonomousAdminImplementation, - AdminHatParams memory adminHat + AdminHatParams calldata adminHat ) internal returns (uint256 adminHatId) { // Create Admin Hat adminHatId = hatsProtocol.getNextId(topHatId); @@ -195,13 +199,14 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { ); // Deploy Decent Autonomous Admin Module, which will wear the Admin Hat - address autonomousAdminModule = moduleProxyFactory.deployModule( + address autonomousAdmin = moduleProxyFactory.deployModule( decentAutonomousAdminImplementation, abi.encodeWithSignature("setUp(bytes)", bytes("")), uint256( keccak256( abi.encodePacked( - // for the salt, we'll concatenate our static salt with the id of the Admin Hat + // for the salt, we'll concatenate our static salt + // with the Admin Hat ID SALT, adminHatId ) @@ -216,7 +221,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { abi.encodeWithSignature( "mintHat(uint256,address)", adminHatId, - autonomousAdminModule + autonomousAdmin ), Enum.Operation.Call ); From b01a2fafd1a5afc5050a67651f80a63a4f214120 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 22:25:38 -0400 Subject: [PATCH 197/206] Rename a file --- ...ectionEligibility.sol => MockHatsElectionsEligibility.sol} | 0 contracts/mocks/MockHatsModuleFactory.sol | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename contracts/mocks/{MockHatsElectionEligibility.sol => MockHatsElectionsEligibility.sol} (100%) diff --git a/contracts/mocks/MockHatsElectionEligibility.sol b/contracts/mocks/MockHatsElectionsEligibility.sol similarity index 100% rename from contracts/mocks/MockHatsElectionEligibility.sol rename to contracts/mocks/MockHatsElectionsEligibility.sol diff --git a/contracts/mocks/MockHatsModuleFactory.sol b/contracts/mocks/MockHatsModuleFactory.sol index accf4cb2..2da8b05d 100644 --- a/contracts/mocks/MockHatsModuleFactory.sol +++ b/contracts/mocks/MockHatsModuleFactory.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; -import {MockHatsElectionsEligibility} from "./MockHatsElectionEligibility.sol"; +import {MockHatsElectionsEligibility} from "./MockHatsElectionsEligibility.sol"; contract MockHatsModuleFactory is IHatsModuleFactory { function createHatsModule( @@ -12,7 +12,7 @@ contract MockHatsModuleFactory is IHatsModuleFactory { bytes calldata _initData, uint256 ) external override returns (address _instance) { - // Deploy a new instance of MockHatsElectionEligibility + // Deploy a new instance of MockHatsElectionsEligibility MockHatsElectionsEligibility newModule = new MockHatsElectionsEligibility(); newModule._setUp(_initData); _instance = address(newModule); From 2691053e3f784772bb37a3500606a2b754b47461 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 22:43:04 -0400 Subject: [PATCH 198/206] Combine the two MockHatsElectionsEligibility set up functions into one --- .../mocks/MockHatsElectionsEligibility.sol | 30 +++++-------------- .../DecentAutonomousAdminV1.test.ts | 8 +++-- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/contracts/mocks/MockHatsElectionsEligibility.sol b/contracts/mocks/MockHatsElectionsEligibility.sol index 74c05783..d452dfc6 100644 --- a/contracts/mocks/MockHatsElectionsEligibility.sol +++ b/contracts/mocks/MockHatsElectionsEligibility.sol @@ -25,37 +25,21 @@ contract MockHatsElectionsEligibility is IHatsElectionsEligibility { _; } - // Can only be called once by the constructor - function setup( - uint128 _firstTermEnd, - address[] calldata _winners - ) external onlyOnce { + function _setUp(bytes calldata _initData) external onlyOnce { + // decode init data + uint128 _firstTermEnd = abi.decode(_initData, (uint128)); require( _firstTermEnd > block.timestamp, - "First term must be in the future" + "First term must end in the future" ); - currentTermEnd = _firstTermEnd; - for (uint256 i; i < _winners.length; ) { - electionResults[_firstTermEnd][_winners[i]] = true; - - unchecked { - ++i; - } - } - } - function _setUp(bytes calldata _initData) external onlyOnce { - // decode init data - uint128 firstTermEnd = abi.decode(_initData, (uint128)); - - // set currentTermEnd - currentTermEnd = firstTermEnd; + currentTermEnd = _firstTermEnd; // open the first election - electionStatus[firstTermEnd] = true; + electionStatus[_firstTermEnd] = true; // log the first term - emit ElectionOpened(firstTermEnd); + emit ElectionOpened(_firstTermEnd); } function elect(uint128 _termEnd, address[] calldata _winners) external { diff --git a/test/autonomous-admin/DecentAutonomousAdminV1.test.ts b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts index 07bcccb7..7f67ec40 100644 --- a/test/autonomous-admin/DecentAutonomousAdminV1.test.ts +++ b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts @@ -1,5 +1,7 @@ import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'; import { expect } from 'chai'; +/* eslint-disable-next-line import/no-extraneous-dependencies */ +import { ethers } from 'ethers'; import hre from 'hardhat'; import { DecentAutonomousAdminV1, @@ -64,9 +66,11 @@ describe('DecentAutonomousAdminHatV1', function () { hatsElectionModule = await new MockHatsElectionsEligibility__factory(deployer).deploy(); // setup the first term - firstTermEnd = (await currentBlockTimestamp()) + 100; - await hatsElectionModule.setup(firstTermEnd, [await firstWearer.getAddress()]); + await hatsElectionModule._setUp( + ethers.AbiCoder.defaultAbiCoder().encode(['uint128'], [firstTermEnd]), + ); + await hatsElectionModule.elect(firstTermEnd, [await firstWearer.getAddress()]); // Create User Hat under the admin hat roleHatId = await hatsProtocol.getNextId(adminHatId); From 11b0c9026d8cb7f6376fe63d68998d9af38b6a83 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 31 Oct 2024 22:46:27 -0400 Subject: [PATCH 199/206] Update variable names --- test/modules/DecentSablierStreamManagement.test.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/modules/DecentSablierStreamManagement.test.ts b/test/modules/DecentSablierStreamManagement.test.ts index 99a20881..88796ab0 100644 --- a/test/modules/DecentSablierStreamManagement.test.ts +++ b/test/modules/DecentSablierStreamManagement.test.ts @@ -46,8 +46,8 @@ describe('DecentSablierStreamManagement', () => { let mockHats: MockHats; let mockHatsAddress: string; - let decentHats: DecentHatsCreationModule; - let decentHatsAddress: string; + let decentHatsCreationModule: DecentHatsCreationModule; + let decentHatsCreationModuleAddress: string; let decentSablierManagement: DecentSablierStreamManagementModule; let decentSablierManagementAddress: string; @@ -92,8 +92,8 @@ describe('DecentSablierStreamManagement', () => { mockHatsAccountImplementation = await new MockHatsAccount__factory(deployer).deploy(); mockHatsAccountImplementationAddress = await mockHatsAccountImplementation.getAddress(); - decentHats = await new DecentHatsCreationModule__factory(deployer).deploy(); - decentHatsAddress = await decentHats.getAddress(); + decentHatsCreationModule = await new DecentHatsCreationModule__factory(deployer).deploy(); + decentHatsCreationModuleAddress = await decentHatsCreationModule.getAddress(); mockHatsModuleFactory = await new MockHatsModuleFactory__factory(deployer).deploy(); moduleProxyFactory = await new ModuleProxyFactory__factory(deployer).deploy(); @@ -152,7 +152,7 @@ describe('DecentSablierStreamManagement', () => { safe: gnosisSafe, to: gnosisSafeAddress, transactionData: GnosisSafeL2__factory.createInterface().encodeFunctionData('enableModule', [ - decentHatsAddress, + decentHatsCreationModuleAddress, ]), signers: [dao], }); @@ -170,7 +170,7 @@ describe('DecentSablierStreamManagement', () => { createAndDeclareTreeWithRolesAndStreamsTx = await executeSafeTransaction({ safe: gnosisSafe, - to: decentHatsAddress, + to: decentHatsCreationModuleAddress, transactionData: DecentHatsCreationModule__factory.createInterface().encodeFunctionData( 'createAndDeclareTree', [ From 1836224fcbda37d98371e35f3912a7cf03ed9839 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 11:02:18 -0400 Subject: [PATCH 200/206] Require that DecentAutonomousAdmin (current and future versions) implement a `version` function --- contracts/autonomous-admin/DecentAutonomousAdminV1.sol | 4 ++++ .../interfaces/autonomous-admin/IDecentAutonomousAdmin.sol | 6 ++++++ .../autonomous-admin/IDecentAutonomousAdminV1.sol | 4 +++- test/autonomous-admin/DecentAutonomousAdminV1.test.ts | 6 ++++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol diff --git a/contracts/autonomous-admin/DecentAutonomousAdminV1.sol b/contracts/autonomous-admin/DecentAutonomousAdminV1.sol index 3588fc29..1216ba64 100644 --- a/contracts/autonomous-admin/DecentAutonomousAdminV1.sol +++ b/contracts/autonomous-admin/DecentAutonomousAdminV1.sol @@ -20,6 +20,10 @@ contract DecentAutonomousAdminV1 is // ////////////////////////////////////////////////////////////// // Public Functions // ////////////////////////////////////////////////////////////// + function version() external pure override returns (uint32) { + return 1; + } + function triggerStartNextTerm(TriggerStartArgs calldata args) public { IHatsElectionsEligibility hatsElectionModule = IHatsElectionsEligibility( args.hatsProtocol.getHatEligibilityModule(args.hatId) diff --git a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol new file mode 100644 index 00000000..b30b46e5 --- /dev/null +++ b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.28; + +interface IDecentAutonomousAdmin { + function version() external view returns (uint32); +} diff --git a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol index bbac8b0d..0f221fc8 100644 --- a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol +++ b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol @@ -1,10 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; +import {IDecentAutonomousAdmin} from "./IDecentAutonomousAdmin.sol"; import {IHats} from "../hats/IHats.sol"; -interface IDecentAutonomousAdminV1 { +interface IDecentAutonomousAdminV1 is IDecentAutonomousAdmin { error NotCurrentWearer(); + struct TriggerStartArgs { address currentWearer; IHats hatsProtocol; diff --git a/test/autonomous-admin/DecentAutonomousAdminV1.test.ts b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts index 7f67ec40..3004067f 100644 --- a/test/autonomous-admin/DecentAutonomousAdminV1.test.ts +++ b/test/autonomous-admin/DecentAutonomousAdminV1.test.ts @@ -93,6 +93,12 @@ describe('DecentAutonomousAdminHatV1', function () { await hatsElectionModule.elect(nextTermEnd, [await secondWearer.getAddress()]); }); + describe('version', function () { + it('should return the correct version', async () => { + expect(await decentAutonomousAdminInstance.version()).to.equal(1); + }); + }); + describe('triggerStartNextTerm', function () { describe('before the first term is over', function () { it('should have correct wearers', async () => { From 3f7ea5ceed72c40ed0b9aada64048f5e651a3c6d Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 11:41:26 -0400 Subject: [PATCH 201/206] SALT -> PEPPER --- contracts/modules/DecentHatsCreationModule.sol | 8 ++++---- contracts/modules/DecentHatsModuleUtils.sol | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/modules/DecentHatsCreationModule.sol b/contracts/modules/DecentHatsCreationModule.sol index 5df50a43..50da9aac 100644 --- a/contracts/modules/DecentHatsCreationModule.sol +++ b/contracts/modules/DecentHatsCreationModule.sol @@ -138,7 +138,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { // Create Top Hat's ERC6551 Account topHatAccount = erc6551Registry.createAccount( hatsAccountImplementation, - SALT, + PEPPER, block.chainid, address(hatsProtocol), topHatId @@ -192,7 +192,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { // Create Admin Hat's ERC6551 Account erc6551Registry.createAccount( hatsAccountImplementation, - SALT, + PEPPER, block.chainid, address(hatsProtocol), adminHatId @@ -205,9 +205,9 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { uint256( keccak256( abi.encodePacked( - // for the salt, we'll concatenate our static salt + // for the salt, we'll concatenate our static PEPPER // with the Admin Hat ID - SALT, + PEPPER, adminHatId ) ) diff --git a/contracts/modules/DecentHatsModuleUtils.sol b/contracts/modules/DecentHatsModuleUtils.sol index f241208b..3dd44c9b 100644 --- a/contracts/modules/DecentHatsModuleUtils.sol +++ b/contracts/modules/DecentHatsModuleUtils.sol @@ -11,7 +11,7 @@ import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; import {ISablierV2LockupLinear} from "../interfaces/sablier/ISablierV2LockupLinear.sol"; abstract contract DecentHatsModuleUtils { - bytes32 public constant SALT = + bytes32 public constant PEPPER = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; struct SablierStreamParams { @@ -112,7 +112,7 @@ abstract contract DecentHatsModuleUtils { hatsProtocol.getNextId(adminHatId), abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] abi.encode(termEndDateTs), - uint256(SALT) + uint256(PEPPER) ); } @@ -196,7 +196,7 @@ abstract contract DecentHatsModuleUtils { return erc6551Registry.createAccount( hatsAccountImplementation, - SALT, + PEPPER, block.chainid, hatsProtocol, hatId From 4fc1b382cfe2c2ab34db5f920ba867557d33943d Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 11:43:38 -0400 Subject: [PATCH 202/206] More thoughtful pragma solidity versioning --- .../interfaces/autonomous-admin/IDecentAutonomousAdmin.sol | 2 +- contracts/modules/DecentHatsModuleUtils.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol index b30b46e5..e6195ebc 100644 --- a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.28; +pragma solidity >=0.8.28; interface IDecentAutonomousAdmin { function version() external view returns (uint32); diff --git a/contracts/modules/DecentHatsModuleUtils.sol b/contracts/modules/DecentHatsModuleUtils.sol index 3dd44c9b..4e25f83f 100644 --- a/contracts/modules/DecentHatsModuleUtils.sol +++ b/contracts/modules/DecentHatsModuleUtils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.28; +pragma solidity >=0.8.28; import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol"; import {IAvatar} from "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol"; From 70d073288a3628a6219cc4b8ad0a3476ec1d1283 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 11:45:49 -0400 Subject: [PATCH 203/206] Rename (and move file) IDecentAutonomousAdmin to IDecentVersion --- .../IDecentAutonomousAdmin.sol => IDecentVersion.sol} | 2 +- .../interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename contracts/interfaces/{autonomous-admin/IDecentAutonomousAdmin.sol => IDecentVersion.sol} (76%) diff --git a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol b/contracts/interfaces/IDecentVersion.sol similarity index 76% rename from contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol rename to contracts/interfaces/IDecentVersion.sol index e6195ebc..29ec7f97 100644 --- a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdmin.sol +++ b/contracts/interfaces/IDecentVersion.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.28; -interface IDecentAutonomousAdmin { +interface IDecentVersion { function version() external view returns (uint32); } diff --git a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol index 0f221fc8..59436154 100644 --- a/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol +++ b/contracts/interfaces/autonomous-admin/IDecentAutonomousAdminV1.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.28; -import {IDecentAutonomousAdmin} from "./IDecentAutonomousAdmin.sol"; +import {IDecentVersion} from "../IDecentVersion.sol"; import {IHats} from "../hats/IHats.sol"; -interface IDecentAutonomousAdminV1 is IDecentAutonomousAdmin { +interface IDecentAutonomousAdminV1 is IDecentVersion { error NotCurrentWearer(); struct TriggerStartArgs { From 44d0c5288e85047ae505acb3b90002b178c101ce Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 11:49:26 -0400 Subject: [PATCH 204/206] Revert "SALT -> PEPPER" This reverts commit 3f7ea5ceed72c40ed0b9aada64048f5e651a3c6d. --- contracts/modules/DecentHatsCreationModule.sol | 8 ++++---- contracts/modules/DecentHatsModuleUtils.sol | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/modules/DecentHatsCreationModule.sol b/contracts/modules/DecentHatsCreationModule.sol index 50da9aac..5df50a43 100644 --- a/contracts/modules/DecentHatsCreationModule.sol +++ b/contracts/modules/DecentHatsCreationModule.sol @@ -138,7 +138,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { // Create Top Hat's ERC6551 Account topHatAccount = erc6551Registry.createAccount( hatsAccountImplementation, - PEPPER, + SALT, block.chainid, address(hatsProtocol), topHatId @@ -192,7 +192,7 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { // Create Admin Hat's ERC6551 Account erc6551Registry.createAccount( hatsAccountImplementation, - PEPPER, + SALT, block.chainid, address(hatsProtocol), adminHatId @@ -205,9 +205,9 @@ contract DecentHatsCreationModule is DecentHatsModuleUtils { uint256( keccak256( abi.encodePacked( - // for the salt, we'll concatenate our static PEPPER + // for the salt, we'll concatenate our static salt // with the Admin Hat ID - PEPPER, + SALT, adminHatId ) ) diff --git a/contracts/modules/DecentHatsModuleUtils.sol b/contracts/modules/DecentHatsModuleUtils.sol index 4e25f83f..7436ba79 100644 --- a/contracts/modules/DecentHatsModuleUtils.sol +++ b/contracts/modules/DecentHatsModuleUtils.sol @@ -11,7 +11,7 @@ import {IHatsModuleFactory} from "../interfaces/hats/IHatsModuleFactory.sol"; import {ISablierV2LockupLinear} from "../interfaces/sablier/ISablierV2LockupLinear.sol"; abstract contract DecentHatsModuleUtils { - bytes32 public constant PEPPER = + bytes32 public constant SALT = 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072; struct SablierStreamParams { @@ -112,7 +112,7 @@ abstract contract DecentHatsModuleUtils { hatsProtocol.getNextId(adminHatId), abi.encode(topHatId, uint256(0)), // [BALLOT_BOX_ID, ADMIN_HAT_ID] abi.encode(termEndDateTs), - uint256(PEPPER) + uint256(SALT) ); } @@ -196,7 +196,7 @@ abstract contract DecentHatsModuleUtils { return erc6551Registry.createAccount( hatsAccountImplementation, - PEPPER, + SALT, block.chainid, hatsProtocol, hatId From 5abdcb27c54c99ec85eb158280d842c34e2d51ca Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 11:51:08 -0400 Subject: [PATCH 205/206] Write test to make sure we have correct SALT --- test/modules/DecentHatsModuleUtils.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/modules/DecentHatsModuleUtils.test.ts b/test/modules/DecentHatsModuleUtils.test.ts index 9f7f4f2d..6fc1d97d 100644 --- a/test/modules/DecentHatsModuleUtils.test.ts +++ b/test/modules/DecentHatsModuleUtils.test.ts @@ -311,4 +311,12 @@ describe('DecentHatsModuleUtils', () => { expect(event.args.totalAmount).to.equal(hre.ethers.parseEther('100')); }); }); + + describe('SALT', () => { + it('should be a static hardcoded value that never changes for any reason', async () => { + expect(await mockDecentHatsModuleUtils.SALT()).to.equal( + '0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072', + ); + }); + }); }); From e44a6c43b7e93d7b29f6f74605bb62402b7354f8 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 1 Nov 2024 12:35:18 -0400 Subject: [PATCH 206/206] Whoops, fix contract name --- deploy/core/017_deploy_DecentAutonomousAdmin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/core/017_deploy_DecentAutonomousAdmin.ts b/deploy/core/017_deploy_DecentAutonomousAdmin.ts index a04d62d7..224f4e99 100644 --- a/deploy/core/017_deploy_DecentAutonomousAdmin.ts +++ b/deploy/core/017_deploy_DecentAutonomousAdmin.ts @@ -3,7 +3,7 @@ import { DeployFunction } from 'hardhat-deploy/types'; import { deployNonUpgradeable } from '../helpers/deployNonUpgradeable'; const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { - await deployNonUpgradeable(hre, 'DecentAutonomousAdmin'); + await deployNonUpgradeable(hre, 'DecentAutonomousAdminV1'); }; export default func;