From 4571fff5c98483f5dbd9c8b3aea7031c90804e7e Mon Sep 17 00:00:00 2001 From: KONFeature Date: Wed, 18 Oct 2023 23:49:06 +0200 Subject: [PATCH 01/16] =?UTF-8?q?=E2=9C=A8=20Diamond=20version=20of=20the?= =?UTF-8?q?=20eip712?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/tokens/EIP712Base.sol | 2 +- contracts/tokens/EIP712Diamond.sol | 103 +++++++++++++++++++++++++++++ contracts/tokens/FrakToken.sol | 1 + contracts/tokens/IFrakToken.sol | 6 -- contracts/utils/FrakErrors.sol | 5 ++ test/tokens/FrakToken.t.sol | 8 +-- 6 files changed, 114 insertions(+), 11 deletions(-) create mode 100644 contracts/tokens/EIP712Diamond.sol diff --git a/contracts/tokens/EIP712Base.sol b/contracts/tokens/EIP712Base.sol index 2b7c2dc..6580ea9 100644 --- a/contracts/tokens/EIP712Base.sol +++ b/contracts/tokens/EIP712Base.sol @@ -28,7 +28,7 @@ contract EIP712Base is Initializable { bytes32 internal domainSeperator; /// @dev Nonces per user - mapping(address => uint256) internal nonces; + mapping(address user => uint256 nonces) internal nonces; /// @dev init function function _initializeEIP712(string memory name) internal onlyInitializing { diff --git a/contracts/tokens/EIP712Diamond.sol b/contracts/tokens/EIP712Diamond.sol new file mode 100644 index 0000000..e624efd --- /dev/null +++ b/contracts/tokens/EIP712Diamond.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GNU GPLv3 +pragma solidity 0.8.21; + +import { Initializable } from "@oz-upgradeable/proxy/utils/Initializable.sol"; + +/// @author @KONFeature +/// @title EIP712Diamond +/// @notice EIP712Diamond base contract with diamond storage +/// @custom:security-contact contact@frak.id +contract EIP712Diamond is Initializable { + struct EIP712Domain { + string name; + string version; + address verifyingContract; + bytes32 salt; + } + + /* -------------------------------------------------------------------------- */ + /* Constant's */ + /* -------------------------------------------------------------------------- */ + + string internal constant ERC712_VERSION = "1"; + + bytes32 internal constant EIP712_DOMAIN_TYPEHASH = + keccak256(bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")); + + /* -------------------------------------------------------------------------- */ + /* Storage */ + /* -------------------------------------------------------------------------- */ + + /// @dev The storage struct for eip 712 + struct EIP712Storage { + /// @dev The current domain seperator + bytes32 _domainSeperator; + /// @dev Nonces per account + mapping(address account => uint256 nonce) _nonces; + } + + /// @dev Access the storage struct of the contract + function _getEIP712Storage() internal pure returns (EIP712Storage storage $) { + assembly { + // keccak256(abi.encode(uint256(keccak256("EIP712Diamond")) - 1)) & ~bytes32(uint256(0xff)) + $.slot := 0x8525956dfba681ee43bd6f7490f38cd4b2b234d15019aabbaf5a265041a3fb00 + } + } + + /// @dev init function + function _initializeEIP712(string memory name) internal onlyInitializing { + // Build and set the domain separator + _getEIP712Storage()._domainSeperator = keccak256( + abi.encode( + EIP712_DOMAIN_TYPEHASH, + keccak256(bytes(name)), + keccak256(bytes(ERC712_VERSION)), + block.chainid, + address(this) + ) + ); + } + + /* -------------------------------------------------------------------------- */ + /* Public view methods */ + /* -------------------------------------------------------------------------- */ + + /// @dev Current domain seperator + function getDomainSeperator() public view returns (bytes32) { + return _getEIP712Storage()._domainSeperator; + } + + /// @dev Get the current 'nonce' for the given 'user' + function getNonce(address user) public view returns (uint256) { + return _getEIP712Storage()._nonces[user]; + } + + /// @dev Use the current 'nonce' for the given 'user' (and increment it) + function useNonce(address user) public returns (uint256) { + return _getEIP712Storage()._nonces[user]++; + } + + /* -------------------------------------------------------------------------- */ + /* Internal functions */ + /* -------------------------------------------------------------------------- */ + + /** + * Accept message hash and returns hash message in EIP712 compatible form + * So that it can be used to recover signer from signature signed using EIP712 formatted data + * https://eips.ethereum.org/EIPS/eip-712 + * "\\x19" makes the encoding deterministic + * "\\x01" is the version byte to make it compatible to EIP-191 + */ + function toTypedMessageHash(bytes32 messageHash) internal view returns (bytes32 digest) { + bytes32 separator = _getEIP712Storage()._domainSeperator; + assembly { + // Compute the digest. + mstore(0x00, 0x1901000000000000) // Store "\x19\x01". + mstore(0x1a, separator) // Store the domain separator. + mstore(0x3a, messageHash) // Store the message hash. + digest := keccak256(0x18, 0x42) + // Restore the part of the free memory slot that was overwritten. + mstore(0x3a, 0) + } + } +} diff --git a/contracts/tokens/FrakToken.sol b/contracts/tokens/FrakToken.sol index 8411413..18a7953 100644 --- a/contracts/tokens/FrakToken.sol +++ b/contracts/tokens/FrakToken.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.21; import { ERC20Upgradeable } from "@oz-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import { FrakRoles } from "../roles/FrakRoles.sol"; +import { InvalidSigner } from "../utils/FrakErrors.sol"; import { FrakAccessControlUpgradeable } from "../roles/FrakAccessControlUpgradeable.sol"; import { IFrakToken } from "./IFrakToken.sol"; import { EIP712Base } from "./EIP712Base.sol"; diff --git a/contracts/tokens/IFrakToken.sol b/contracts/tokens/IFrakToken.sol index 5295e55..ece1efd 100644 --- a/contracts/tokens/IFrakToken.sol +++ b/contracts/tokens/IFrakToken.sol @@ -8,15 +8,9 @@ import { IERC20Upgradeable } from "@oz-upgradeable/token/ERC20/IERC20Upgradeable /// @notice Interface for the FrakToken /// @custom:security-contact contact@frak.id interface IFrakToken is IERC20Upgradeable { - /// @dev error throwned when the signer is invalid - error InvalidSigner(); - /// @dev error throwned when the contract cap is exceeded error CapExceed(); - /// @dev error throwned when the permit delay is expired - error PermitDelayExpired(); - /// @dev Mint `amount` of FRK to `to` function mint(address to, uint256 amount) external; diff --git a/contracts/utils/FrakErrors.sol b/contracts/utils/FrakErrors.sol index 0cfe17c..7fcfae0 100644 --- a/contracts/utils/FrakErrors.sol +++ b/contracts/utils/FrakErrors.sol @@ -12,3 +12,8 @@ error NoReward(); error RewardTooLarge(); error BadgeTooLarge(); error InvalidFraktionType(); + +/// @dev error throwned when the signer is invalid +error InvalidSigner(); +/// @dev error throwned when the permit delay is expired +error PermitDelayExpired(); diff --git a/test/tokens/FrakToken.t.sol b/test/tokens/FrakToken.t.sol index 8328f82..265e132 100644 --- a/test/tokens/FrakToken.t.sol +++ b/test/tokens/FrakToken.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.21; import { FrakTest } from "../FrakTest.sol"; -import { NotAuthorized } from "contracts/utils/FrakErrors.sol"; +import { NotAuthorized, PermitDelayExpired, InvalidSigner } from "contracts/utils/FrakErrors.sol"; import { FrakToken } from "contracts/tokens/FrakToken.sol"; import { IFrakToken } from "contracts/tokens/IFrakToken.sol"; @@ -101,7 +101,7 @@ contract FrakTokenTest is FrakTest { (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitSignature(contentOwner, 1 ether, block.timestamp - 1); // Perform the permit op & ensure it's valid - vm.expectRevert(IFrakToken.PermitDelayExpired.selector); + vm.expectRevert(PermitDelayExpired.selector); frakToken.permit(user, contentOwner, 1 ether, block.timestamp - 1, v, r, s); } @@ -110,7 +110,7 @@ contract FrakTokenTest is FrakTest { (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitSignature(contentOwner, 1 ether, block.timestamp); // Perform the permit op & ensure it's valid - vm.expectRevert(IFrakToken.InvalidSigner.selector); + vm.expectRevert(InvalidSigner.selector); frakToken.permit(address(1), contentOwner, 1 ether, block.timestamp, v, r, s); } @@ -128,7 +128,7 @@ contract FrakTokenTest is FrakTest { ); // Perform the permit op & ensure it's valid - vm.expectRevert(IFrakToken.InvalidSigner.selector); + vm.expectRevert(InvalidSigner.selector); frakToken.permit(address(1), contentOwner, 1 ether, block.timestamp, v, r, s); } From aa28e3fe35e3d9cfd823be6d3daf12da467eda91 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Wed, 18 Oct 2023 23:56:43 +0200 Subject: [PATCH 02/16] =?UTF-8?q?=E2=9C=A8=20Add=20a=20function=20to=20per?= =?UTF-8?q?mit=20all=20the=20transfer=20from=20the=20erc1155?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/fraktions/FraktionTokens.sol | 63 ++++++++++++++++++- contracts/{tokens => utils}/EIP712Diamond.sol | 9 ++- 2 files changed, 68 insertions(+), 4 deletions(-) rename contracts/{tokens => utils}/EIP712Diamond.sol (92%) diff --git a/contracts/fraktions/FraktionTokens.sol b/contracts/fraktions/FraktionTokens.sol index 55f3421..4b55f50 100644 --- a/contracts/fraktions/FraktionTokens.sol +++ b/contracts/fraktions/FraktionTokens.sol @@ -8,13 +8,15 @@ import { FraktionId } from "../libs/FraktionId.sol"; import { ArrayLib } from "../libs/ArrayLib.sol"; import { FrakRoles } from "../roles/FrakRoles.sol"; import { FrakAccessControlUpgradeable } from "../roles/FrakAccessControlUpgradeable.sol"; -import { InvalidArray } from "../utils/FrakErrors.sol"; +import { InvalidArray, InvalidSigner } from "../utils/FrakErrors.sol"; +import { EIP712Diamond } from "../utils/EIP712Diamond.sol"; +import { ECDSA } from "solady/utils/ECDSA.sol"; /// @author @KONFeature /// @title FraktionTokens /// @notice ERC1155 for the Frak Fraktions tokens, used as ownership proof for a content, or investisment proof /// @custom:security-contact contact@frak.id -contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable { +contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP712Diamond { /* -------------------------------------------------------------------------- */ /* Custom error's */ /* -------------------------------------------------------------------------- */ @@ -34,6 +36,9 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable { /// @dev 'bytes4(keccak256("SupplyUpdateNotAllowed()"))' uint256 private constant _SUPPLY_UPDATE_NOT_ALLOWED_SELECTOR = 0x48385ebd; + /// @dev 'bytes4(keccak256(bytes("PermitDelayExpired()")))' + uint256 private constant _PERMIT_DELAYED_EXPIRED_SELECTOR = 0x95fc6e60; + /* -------------------------------------------------------------------------- */ /* Event's */ /* -------------------------------------------------------------------------- */ @@ -81,6 +86,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable { function initialize(string calldata metadatalUrl) external initializer { __ERC1155_init(metadatalUrl); __FrakAccessControlUpgradeable_Minter_init(); + _initializeEIP712("Fraktions"); // Set the initial content id _currentContentId = 1; } @@ -202,6 +208,59 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable { _burn(msg.sender, FraktionId.unwrap(id), amount); } + /* -------------------------------------------------------------------------- */ + /* Allowance methods */ + /* -------------------------------------------------------------------------- */ + + /// @dev Signature check to allow a user to transfer ERC-1155 on the behalf of the owner + function permitAllTransfer( + address owner, + address spender, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) + external + payable + override + { + // Ensure deadline is valid + assembly { + if gt(timestamp(), deadline) { + mstore(0x00, _PERMIT_DELAYED_EXPIRED_SELECTOR) + revert(0x1c, 0x04) + } + } + + // Unchecked because the only math done is incrementing + // the owner's nonce which cannot realistically overflow. + unchecked { + address recoveredAddress = ECDSA.recover( + toTypedMessageHash( + keccak256( + abi.encode( + keccak256("PermitAllTransfer(address owner,address spender,uint256 nonce,uint256 deadline)"), + owner, + spender, + _useNonce(owner), + deadline + ) + ) + ), + v, + r, + s + ); + + // Don't need to check for 0 address, or send event's, since approve already do it for us + if (recoveredAddress != owner) revert InvalidSigner(); + + // Approve the token + _setApprovalForAll(recoveredAddress, spender, true); + } + } + /* -------------------------------------------------------------------------- */ /* Internal callback function's */ /* -------------------------------------------------------------------------- */ diff --git a/contracts/tokens/EIP712Diamond.sol b/contracts/utils/EIP712Diamond.sol similarity index 92% rename from contracts/tokens/EIP712Diamond.sol rename to contracts/utils/EIP712Diamond.sol index e624efd..0c9466d 100644 --- a/contracts/tokens/EIP712Diamond.sol +++ b/contracts/utils/EIP712Diamond.sol @@ -7,7 +7,8 @@ import { Initializable } from "@oz-upgradeable/proxy/utils/Initializable.sol"; /// @title EIP712Diamond /// @notice EIP712Diamond base contract with diamond storage /// @custom:security-contact contact@frak.id -contract EIP712Diamond is Initializable { +/// TODO: Use OZ5 -> Import another submodule based on OZ 5.0 +contract EIP712Diamond { struct EIP712Domain { string name; string version; @@ -45,7 +46,11 @@ contract EIP712Diamond is Initializable { } /// @dev init function - function _initializeEIP712(string memory name) internal onlyInitializing { + function _initializeEIP712(string memory name) internal { + // Ensure the domain separator is currently empty + bytes32 domainSeparator = _getEIP712Storage()._domainSeperator; + if (domainSeparator != 0x0) revert(); + // Build and set the domain separator _getEIP712Storage()._domainSeperator = keccak256( abi.encode( From d49102497337681f9c99ef4c2e66604dbe3ae982 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 00:11:41 +0200 Subject: [PATCH 03/16] =?UTF-8?q?=E2=9C=A8=F0=9F=9A=A7=20Startup=20wallet?= =?UTF-8?q?=20migrator=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/fraktions/FraktionTokens.sol | 21 ++++--- contracts/wallets/WalletMigrator.sol | 76 ++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 contracts/wallets/WalletMigrator.sol diff --git a/contracts/fraktions/FraktionTokens.sol b/contracts/fraktions/FraktionTokens.sol index 4b55f50..c2970b7 100644 --- a/contracts/fraktions/FraktionTokens.sol +++ b/contracts/fraktions/FraktionTokens.sol @@ -18,7 +18,7 @@ import { ECDSA } from "solady/utils/ECDSA.sol"; /// @custom:security-contact contact@frak.id contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP712Diamond { /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev Error throwned when we don't have enough supply to mint a new fNFT @@ -40,7 +40,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP uint256 private constant _PERMIT_DELAYED_EXPIRED_SELECTOR = 0x95fc6e60; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when the supply of a fraktion is updated @@ -75,7 +75,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP mapping(uint256 id => uint256 availableSupply) private _availableSupplies; /// @dev Tell us if that fraktion is supply aware or not - /// @notice unused now since we rely on the fraktion type to know if it's supply aware or not + /// @notice unused now since we rely on the fraktion type to know if it is supply aware or not mapping(uint256 => bool) private _unused1; /// @custom:oz-upgrades-unsafe-allow constructor @@ -92,7 +92,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP } /* -------------------------------------------------------------------------- */ - /* External write function's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /// @dev Mint a new content, return the id of the built content @@ -223,7 +223,6 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP ) external payable - override { // Ensure deadline is valid assembly { @@ -243,7 +242,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP keccak256("PermitAllTransfer(address owner,address spender,uint256 nonce,uint256 deadline)"), owner, spender, - _useNonce(owner), + useNonce(owner), deadline ) ) @@ -253,7 +252,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP s ); - // Don't need to check for 0 address, or send event's, since approve already do it for us + // Don't need to check for 0 address, or send event, since approve already do it for us if (recoveredAddress != owner) revert InvalidSigner(); // Approve the token @@ -262,7 +261,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP } /* -------------------------------------------------------------------------- */ - /* Internal callback function's */ + /* Internal callback functions */ /* -------------------------------------------------------------------------- */ /// @dev Handle the transfer token (so update the content investor, change the owner of some content etc) @@ -282,7 +281,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP // Assembly block to check supply and decrease it if needed assembly { - // Base offset to access array element's + // Base offset to access array elements let currOffset := 0x20 let offsetEnd := add(currOffset, shl(5, mload(ids))) @@ -335,7 +334,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP override { assembly { - // Base offset to access array element's + // Base offset to access array elements let currOffset := 0x20 let offsetEnd := add(currOffset, shl(5, mload(ids))) @@ -381,7 +380,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP } /* -------------------------------------------------------------------------- */ - /* Public view function's */ + /* Public view functions */ /* -------------------------------------------------------------------------- */ /// @dev Batch balance of for single address diff --git a/contracts/wallets/WalletMigrator.sol b/contracts/wallets/WalletMigrator.sol new file mode 100644 index 0000000..f7bbd85 --- /dev/null +++ b/contracts/wallets/WalletMigrator.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GNU GPLv3 +pragma solidity 0.8.21; + +import { IFrakToken } from "../tokens/IFrakToken.sol"; +import { FraktionTokens } from "../fraktions/FraktionTokens.sol"; +import { IPushPullReward } from "../utils/IPushPullReward.sol"; +import { Multicallable } from "solady/utils/Multicallable.sol"; + +/// @author @KONFeature +/// @title WalletMigrator +/// @notice Wallet migrator, used to migrate wallet from one to another +/// @custom:security-contact contact@frak.id +contract WalletMigrator is Multicallable { + /* -------------------------------------------------------------------------- */ + /* Storages */ + /* -------------------------------------------------------------------------- */ + + /// @dev Our frak and fraktions tokens + IFrakToken private immutable frkToken; + FraktionTokens private immutable fraktionTokens; + + /// @dev Our different reward pools + IPushPullReward private immutable rewarderPool; + IPushPullReward private immutable contentPool; + IPushPullReward private immutable referralPool; + + /// @dev Create this wallet migrator, with all the addresses + constructor( + address _frkToken, + address _fraktionTokens, + address _rewarder, + address _contentPool, + address _referralPool + ) { + // Set our tokens + frkToken = IFrakToken(_frkToken); + fraktionTokens = FraktionTokens(_fraktionTokens); + + // Set our reward pools + rewarderPool = IPushPullReward(_rewarder); + contentPool = IPushPullReward(_contentPool); + referralPool = IPushPullReward(_referralPool); + } + + /* -------------------------------------------------------------------------- */ + /* Public migration functions */ + /* -------------------------------------------------------------------------- */ + + /// @dev Claim all the founds for a user at once + function claimAllFounds() public { + _claimAllFounds(msg.sender); + } + + /// @dev Migrate the wallet from the old to the new one + function migrateFrk(address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { + // First we will claim all the founds of a user + _claimAllFounds(msg.sender); + + // We use the signature to allow the transfer all the FRK of the user + frkToken.permit(msg.sender, address(this), type(uint256).max, deadline, v, r, s); + + // And finally, we transfer all the FRK of the user to the new wallet + frkToken.transferFrom(msg.sender, newWallet, frkToken.balanceOf(msg.sender)); + } + + /* -------------------------------------------------------------------------- */ + /* Internal migration functions */ + /* -------------------------------------------------------------------------- */ + + /// @dev Claim all the founds for a user at once + function _claimAllFounds(address user) internal { + rewarderPool.withdrawFounds(user); + contentPool.withdrawFounds(user); + referralPool.withdrawFounds(user); + } +} From 7f751085f36e5daa4ca78cb67b3c9b9c20ca569f Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 10:18:25 +0200 Subject: [PATCH 04/16] =?UTF-8?q?=E2=9C=A8=F0=9F=9A=A7=20Adding=20the=20av?= =?UTF-8?q?ailability=20to=20migrate=20all=20fraktions=20&=20matic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/fraktions/FraktionTokens.sol | 17 +++++++++++++ contracts/wallets/WalletMigrator.sol | 33 ++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/contracts/fraktions/FraktionTokens.sol b/contracts/fraktions/FraktionTokens.sol index c2970b7..cb72ad3 100644 --- a/contracts/fraktions/FraktionTokens.sol +++ b/contracts/fraktions/FraktionTokens.sol @@ -11,6 +11,7 @@ import { FrakAccessControlUpgradeable } from "../roles/FrakAccessControlUpgradea import { InvalidArray, InvalidSigner } from "../utils/FrakErrors.sol"; import { EIP712Diamond } from "../utils/EIP712Diamond.sol"; import { ECDSA } from "solady/utils/ECDSA.sol"; +import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol"; /// @author @KONFeature /// @title FraktionTokens @@ -208,6 +209,22 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP _burn(msg.sender, FraktionId.unwrap(id), amount); } + /// @dev Transfer all the fraktions from the given user to a new one + function transferAllFrom(address from, address to, uint256[] calldata ids) external payable { + // Build the amounts matching the ids + uint256 length = ids.length; + uint256[] memory amounts = new uint256[](length); + for (uint256 i = 0; i < length;) { + unchecked { + amounts[i] = balanceOf(from, ids[i]); + ++i; + } + } + + // Perform the batch transfer operations + safeBatchTransferFrom(from, to, ids, amounts, ""); + } + /* -------------------------------------------------------------------------- */ /* Allowance methods */ /* -------------------------------------------------------------------------- */ diff --git a/contracts/wallets/WalletMigrator.sol b/contracts/wallets/WalletMigrator.sol index f7bbd85..d91548a 100644 --- a/contracts/wallets/WalletMigrator.sol +++ b/contracts/wallets/WalletMigrator.sol @@ -5,12 +5,15 @@ import { IFrakToken } from "../tokens/IFrakToken.sol"; import { FraktionTokens } from "../fraktions/FraktionTokens.sol"; import { IPushPullReward } from "../utils/IPushPullReward.sol"; import { Multicallable } from "solady/utils/Multicallable.sol"; +import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol"; /// @author @KONFeature /// @title WalletMigrator /// @notice Wallet migrator, used to migrate wallet from one to another /// @custom:security-contact contact@frak.id contract WalletMigrator is Multicallable { + using SafeTransferLib for address; + /* -------------------------------------------------------------------------- */ /* Storages */ /* -------------------------------------------------------------------------- */ @@ -51,16 +54,36 @@ contract WalletMigrator is Multicallable { _claimAllFounds(msg.sender); } - /// @dev Migrate the wallet from the old to the new one + /// @dev Migrate all the FRK of the current user to the `newWallet` function migrateFrk(address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { - // First we will claim all the founds of a user - _claimAllFounds(msg.sender); - // We use the signature to allow the transfer all the FRK of the user frkToken.permit(msg.sender, address(this), type(uint256).max, deadline, v, r, s); // And finally, we transfer all the FRK of the user to the new wallet - frkToken.transferFrom(msg.sender, newWallet, frkToken.balanceOf(msg.sender)); + address(frkToken).safeTransferFrom(msg.sender, newWallet, frkToken.balanceOf(msg.sender)); + } + + /// @dev Migrate all the fraktions to the `newWallet`at once + function migrateFraktions( + address newWallet, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s, + uint256[] calldata ids + ) + external + { + // We use the signature to allow the transfer all the FRK of the user + fraktionTokens.permitAllTransfer(msg.sender, address(this), deadline, v, r, s); + + // And finally, we transfer all the FRK of the user to the new wallet + fraktionTokens.transferAllFrom(msg.sender, newWallet, ids); + } + + /// @dev Send all the matic of the sender to the `newWallet` + function migrateMatic(address newWallet) external { + newWallet.safeTransferAllETH(); } /* -------------------------------------------------------------------------- */ From dc3bd824fabf730f0c3f178adb1377925bf6d47f Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 11:53:32 +0200 Subject: [PATCH 05/16] =?UTF-8?q?=F0=9F=A7=AA=20Startup=20new=20fraktions?= =?UTF-8?q?=20unit=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 107 +++++++++++++------------ contracts/fraktions/FraktionTokens.sol | 2 +- test/FrakTest.sol | 73 ++++++++++++----- test/fraktions/FraktionTokens.t.sol | 107 ++++++++++++++++++++++++- 4 files changed, 215 insertions(+), 74 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index e974f49..59366b9 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -2,14 +2,14 @@ ContentPoolTest:test_addReward_InvalidReward_ko() (gas: 28972) ContentPoolTest:test_addReward_InvalidRole_ko() (gas: 17640) ContentPoolTest:test_addReward_ok() (gas: 66202) ContentPoolTest:test_canBeDeployedAndInit_ok() (gas: 2820972) -ContentPoolTest:test_getRewardStates_ok() (gas: 223640) +ContentPoolTest:test_getRewardStates_ok() (gas: 223662) ContentPoolTest:test_initialize_InitTwice_ko() (gas: 17982) -ContentPoolTest:test_participantStates_ok() (gas: 220730) +ContentPoolTest:test_participantStates_ok() (gas: 220752) ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428687) -ContentPoolTest:test_updateUserAndPool_ok() (gas: 325512) -ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539456) -ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713219) -ContentPoolTest:test_updateUser_ok() (gas: 400248) +ContentPoolTest:test_updateUserAndPool_ok() (gas: 325494) +ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539500) +ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713307) +ContentPoolTest:test_updateUser_ok() (gas: 400284) FrakTeasuryWalletTest:test_canBeDeployedAndInit_ok() (gas: 1773426) FrakTeasuryWalletTest:test_initialize_InitTwice_ko() (gas: 17937) FrakTeasuryWalletTest:test_transferBatch_InvalidArray_ko() (gas: 28753) @@ -24,7 +24,7 @@ FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11304244) FrakTeasuryWalletTest:test_transfer_NotMinter_ko() (gas: 17684) FrakTeasuryWalletTest:test_transfer_RewardTooLarge_ko() (gas: 20534) FrakTeasuryWalletTest:test_transfer_ok() (gas: 136061) -FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3621) +FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3554) FrakTokenTest:test_burn_ok() (gas: 53287) FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 2502575) FrakTokenTest:test_cap_ok() (gas: 10366) @@ -39,40 +39,45 @@ FrakTokenTest:test_permit_InvalidNonce_ko() (gas: 50226) FrakTokenTest:test_permit_InvalidSigner_ko() (gas: 53835) FrakTokenTest:test_permit_ok() (gas: 77672) FrakTokenTest:test_symbol_ok() (gas: 14797) -FraktionCostBadgesTest:test_defaultPrice_InvalidFraktionType_ko() (gas: 43272) +FraktionCostBadgesTest:test_defaultPrice_InvalidFraktionType_ko() (gas: 46597) FraktionCostBadgesTest:test_defaultPrice_ok() (gas: 26214) FraktionCostBadgesTest:test_updatePrice_InvalidFraktionType_ko() (gas: 46266) FraktionCostBadgesTest:test_updatePrice_InvalidRole_ko() (gas: 17661) FraktionCostBadgesTest:test_updatePrice_ok() (gas: 126566) -FraktionTokensTest:test_addContent_InvalidRole_ko() (gas: 18772) -FraktionTokensTest:test_addContent_SupplyUpdateNotAllowed_ko() (gas: 69957) -FraktionTokensTest:test_addContent_ok() (gas: 329982) -FraktionTokensTest:test_batchBalance_ok() (gas: 59813) -FraktionTokensTest:test_burn_ok() (gas: 49562) -FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 3382823) -FraktionTokensTest:test_initialize_InitTwice_ko() (gas: 16008) -FraktionTokensTest:test_ownerOf_ok() (gas: 16844) -FraktionTokensTest:test_setUpTransferCallback_ok() (gas: 367201) -FraktionTokensTest:test_supply_InvalidRole_ko() (gas: 53345) -FraktionTokensTest:test_supply_SupplyUpdateNotAllowed_ko() (gas: 45822) -FraktionTokensTest:test_supply_ok() (gas: 87692) +FraktionTokensTest:test_addContent_InvalidRole_ko() (gas: 18848) +FraktionTokensTest:test_addContent_SupplyUpdateNotAllowed_ko() (gas: 75153) +FraktionTokensTest:test_addContent_ok() (gas: 330042) +FraktionTokensTest:test_batchBalance_ok() (gas: 59879) +FraktionTokensTest:test_burn_ok() (gas: 49561) +FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 3732947) +FraktionTokensTest:test_initialize_InitTwice_ko() (gas: 16030) +FraktionTokensTest:test_ownerOf_ok() (gas: 16910) +FraktionTokensTest:test_permitTransferAll_DelayExpired_ko() (gas: 27984) +FraktionTokensTest:test_permitTransferAll_InvalidNonce_ko() (gas: 50430) +FraktionTokensTest:test_permitTransferAll_InvalidSigner_ko() (gas: 53829) +FraktionTokensTest:test_permitTransferAll_ok() (gas: 77652) +FraktionTokensTest:test_setUpTransferCallback_ok() (gas: 367334) +FraktionTokensTest:test_supply_InvalidRole_ko() (gas: 53411) +FraktionTokensTest:test_supply_SupplyUpdateNotAllowed_ko() (gas: 45910) +FraktionTokensTest:test_supply_ok() (gas: 87688) +FraktionTokensTest:test_transferAllFrom_ok() (gas: 189678) MinterTest:test_addContent_InvalidRole_ko() (gas: 17808) -MinterTest:test_addContent_InvalidSupply_ko() (gas: 55648) -MinterTest:test_addContent_ok() (gas: 194493) -MinterTest:test_benchmarkAddContent_ok() (gas: 695249) +MinterTest:test_addContent_InvalidSupply_ko() (gas: 62459) +MinterTest:test_addContent_ok() (gas: 194423) +MinterTest:test_benchmarkAddContent_ok() (gas: 695381) MinterTest:test_canBeDeployedAndInit_ok() (gas: 2267698) -MinterTest:test_increaseSupply_InvalidRole_ko() (gas: 62383) -MinterTest:test_increaseSupply_ok() (gas: 75939) +MinterTest:test_increaseSupply_InvalidRole_ko() (gas: 62382) +MinterTest:test_increaseSupply_ok() (gas: 75937) MinterTest:test_initialize_InitTwice_ko() (gas: 22408) -MinterTest:test_mintFraktionForUser_ok() (gas: 212716) -MinterTest:test_mintFraktion_TooManyFraktion_ko() (gas: 216239) -MinterTest:test_mintFraktion_ok() (gas: 210175) -MinterTest:test_mintFreeFraktionForUser_ok() (gas: 60193) +MinterTest:test_mintFraktionForUser_ok() (gas: 212738) +MinterTest:test_mintFraktion_TooManyFraktion_ko() (gas: 216261) +MinterTest:test_mintFraktion_ok() (gas: 210197) +MinterTest:test_mintFreeFraktionForUser_ok() (gas: 60215) MinterTest:test_mintFreeFraktion_ExpectingOnlyFreeFraktion_ko() (gas: 40161) -MinterTest:test_mintFreeFraktion_TooManyFraktion_ko() (gas: 66087) -MinterTest:test_mintFreeFraktion_ok() (gas: 62897) -MultiVestingWalletsTest:test_canBeDeployedAndInit_ok() (gas: 2667336) -MultiVestingWalletsTest:test_createVestBatch() (gas: 210722) +MinterTest:test_mintFreeFraktion_TooManyFraktion_ko() (gas: 66109) +MinterTest:test_mintFreeFraktion_ok() (gas: 62919) +MultiVestingWalletsTest:test_canBeDeployedAndInit_ok() (gas: 2732546) +MultiVestingWalletsTest:test_createVestBatch() (gas: 210700) MultiVestingWalletsTest:test_createVestBatch_ArrayInvalidLength_ko() (gas: 79027) MultiVestingWalletsTest:test_createVestBatch_EmptyArray_ko() (gas: 78827) MultiVestingWalletsTest:test_createVestBatch_NotEnoughReserve_ko() (gas: 85446) @@ -85,18 +90,18 @@ MultiVestingWalletsTest:test_createVest_InvalidStartDate_ko() (gas: 80499) MultiVestingWalletsTest:test_createVest_NotEnoughReserve_ko() (gas: 84011) MultiVestingWalletsTest:test_createVest_NotManager_ko() (gas: 79610) MultiVestingWalletsTest:test_createVest_TooLargeReward_ko() (gas: 82001) -MultiVestingWalletsTest:test_createVest_ok() (gas: 209042) +MultiVestingWalletsTest:test_createVest_ok() (gas: 209020) MultiVestingWalletsTest:test_decimals_ok() (gas: 10391) -MultiVestingWalletsTest:test_initialize_InitTwice_ko() (gas: 17982) +MultiVestingWalletsTest:test_initialize_InitTwice_ko() (gas: 18027) MultiVestingWalletsTest:test_name_ok() (gas: 12085) -MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 232525) -MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228343) -MultiVestingWalletsTest:test_release_ok() (gas: 237783) -MultiVestingWalletsTest:test_symbol_ok() (gas: 12073) -MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103722) -MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 211179) -MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209436) -MultiVestingWalletsTest:test_transfer_ok() (gas: 226494) +MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233561) +MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228498) +MultiVestingWalletsTest:test_release_ok() (gas: 237964) +MultiVestingWalletsTest:test_symbol_ok() (gas: 12117) +MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103656) +MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208232) +MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209435) +MultiVestingWalletsTest:test_transfer_ok() (gas: 226427) ReferralPoolTest:test_canBeDeployedAndInit_ok() (gas: 1692225) ReferralPoolTest:test_initialize_InitTwice_ko() (gas: 17881) RewarderConfigTest:test_canBeDeployedAndInit_ok() (gas: 2600249) @@ -109,7 +114,7 @@ RewarderConfigTest:test_updateListenerBadge_InvalidRole_ko() (gas: 17711) RewarderConfigTest:test_updateListenerBadge_ok() (gas: 46543) RewarderConfigTest:test_updateTpu_InvalidRole_ko() (gas: 15412) RewarderConfigTest:test_updateTpu_ok() (gas: 23775) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139334) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139378) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_EmptyAmount_ko() (gas: 81286) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidArray_ko() (gas: 79510) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidRole_ko() (gas: 80397) @@ -120,15 +125,15 @@ RewarderDirectPaymentTest:test_payUserDirectly_InvalidAddress_ko() (gas: 77885) RewarderDirectPaymentTest:test_payUserDirectly_InvalidReward_ko() (gas: 88533) RewarderDirectPaymentTest:test_payUserDirectly_InvalidRole_ko() (gas: 79215) RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105700) -RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212408) -RewarderTest:test_pay_FreeFraktion_ok() (gas: 191901) +RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212716) +RewarderTest:test_pay_FreeFraktion_ok() (gas: 191967) RewarderTest:test_pay_InvalidAddress_ko() (gas: 21620) RewarderTest:test_pay_InvalidArray_ko() (gas: 38041) -RewarderTest:test_pay_InvalidContent_ko() (gas: 56805) +RewarderTest:test_pay_InvalidContent_ko() (gas: 56871) RewarderTest:test_pay_InvalidRoles_ko() (gas: 21259) -RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367403) -RewarderTest:test_pay_PayedFraktions_TooMuchListenCounts_ko() (gas: 167339) -RewarderTest:test_pay_PayedFraktions_ok() (gas: 405269) -RewarderTest:test_pay_TooLargeReward_ko() (gas: 230900) +RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367557) +RewarderTest:test_pay_PayedFraktions_TooMuchListenCounts_ko() (gas: 167427) +RewarderTest:test_pay_PayedFraktions_ok() (gas: 405423) +RewarderTest:test_pay_TooLargeReward_ko() (gas: 231010) VestingWalletFactoryTest:test_canBeDeployedAndInit_ok() (gas: 2093328) VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) \ No newline at end of file diff --git a/contracts/fraktions/FraktionTokens.sol b/contracts/fraktions/FraktionTokens.sol index cb72ad3..6e7da4b 100644 --- a/contracts/fraktions/FraktionTokens.sol +++ b/contracts/fraktions/FraktionTokens.sol @@ -221,7 +221,7 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP } } - // Perform the batch transfer operations + // Perform the batch transfer safeBatchTransferFrom(from, to, ids, amounts, ""); } diff --git a/test/FrakTest.sol b/test/FrakTest.sol index 63f6637..5cbf049 100644 --- a/test/FrakTest.sol +++ b/test/FrakTest.sol @@ -21,6 +21,9 @@ contract FrakTest is PRBTest { bytes32 constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + bytes32 constant PERMIT_TRANSFER_ALL_TYPEHASH = + keccak256("PermitAllTransfer(address owner,address spender,uint256 nonce,uint256 deadline)"); + // User accounts address foundation; address deployer; @@ -247,7 +250,7 @@ contract FrakTest is PRBTest { } /* -------------------------------------------------------------------------- */ - /* Utils, to ease the test process */ + /* Modifier helpers */ /* -------------------------------------------------------------------------- */ modifier asDeployer() { @@ -271,6 +274,36 @@ contract FrakTest is PRBTest { _; } + function _newUser(string memory label) internal returns (address addr) { + addr = address(bytes20(keccak256(abi.encode(label)))); + vm.label(addr, label); + } + + function _newUserWithPrivKey(string memory label) internal returns (address addr, uint256 privKey) { + privKey = uint256(keccak256(abi.encode(label))); + addr = vm.addr(privKey); + vm.label(addr, label); + } + + /// @dev Deploy the given proxy + function _deployProxy( + address logic, + bytes memory init, + string memory label + ) + internal + returns (address createdAddress) + { + ERC1967Proxy proxyTemp = new ERC1967Proxy(logic, init); + createdAddress = address(proxyTemp); + vm.label(createdAddress, label); + } + + /* -------------------------------------------------------------------------- */ + /* Signature helpers */ + /* -------------------------------------------------------------------------- */ + + /// @dev Generate the erc20 permit signature function _generateUserPermitSignature( address to, uint256 amount, @@ -292,28 +325,26 @@ contract FrakTest is PRBTest { ); } - function _newUser(string memory label) internal returns (address addr) { - addr = address(bytes20(keccak256(abi.encode(label)))); - vm.label(addr, label); - } - - function _newUserWithPrivKey(string memory label) internal returns (address addr, uint256 privKey) { - privKey = uint256(keccak256(abi.encode(label))); - addr = vm.addr(privKey); - vm.label(addr, label); - } - - /// @dev Deploy the given proxy - function _deployProxy( - address logic, - bytes memory init, - string memory label + /// @dev Generate a permit signature for the fraktion tokens + function _generateUserPermitTransferAllSignature( + address to, + uint256 deadline ) internal - returns (address createdAddress) + view + returns (uint8, bytes32, bytes32) { - ERC1967Proxy proxyTemp = new ERC1967Proxy(logic, init); - createdAddress = address(proxyTemp); - vm.label(createdAddress, label); + return vm.sign( + userPrivKey, + keccak256( + abi.encodePacked( + "\x19\x01", + fraktionTokens.getDomainSeperator(), + keccak256( + abi.encode(PERMIT_TRANSFER_ALL_TYPEHASH, user, to, fraktionTokens.getNonce(user), deadline) + ) + ) + ) + ); } } diff --git a/test/fraktions/FraktionTokens.t.sol b/test/fraktions/FraktionTokens.t.sol index f523e4a..d0a8cad 100644 --- a/test/fraktions/FraktionTokens.t.sol +++ b/test/fraktions/FraktionTokens.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.21; import { FrakTest } from "../FrakTest.sol"; -import { NotAuthorized, InvalidArray } from "contracts/utils/FrakErrors.sol"; +import { NotAuthorized, InvalidArray, InvalidSigner, PermitDelayExpired } from "contracts/utils/FrakErrors.sol"; import { FraktionTokens } from "contracts/fraktions/FraktionTokens.sol"; import { FraktionTransferCallback } from "contracts/fraktions/FraktionTransferCallback.sol"; import { ContentId, ContentIdLib } from "contracts/libs/ContentId.sol"; @@ -197,6 +197,111 @@ contract FraktionTokensTest is FrakTest { assertEq(fraktionTokens.ownerOf(contentId), contentOwner); } + /* -------------------------------------------------------------------------- */ + /* Permit transfer all */ + /* -------------------------------------------------------------------------- */ + + function test_permitTransferAll_ok() public { + // Generate signature + (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(contentOwner, block.timestamp); + + // Perform the permit op & ensure it's valid + fraktionTokens.permitAllTransfer(user, contentOwner, block.timestamp, v, r, s); + + assertEq(fraktionTokens.isApprovedForAll(user, contentOwner), true); + } + + function test_permitTransferAll_DelayExpired_ko() public { + // Generate signature + (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(contentOwner, block.timestamp - 1); + + // Perform the permit op & ensure it's valid + vm.expectRevert(PermitDelayExpired.selector); + fraktionTokens.permitAllTransfer(user, contentOwner, block.timestamp - 1, v, r, s); + } + + function test_permitTransferAll_InvalidSigner_ko() public { + // Generate signature + (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(contentOwner, block.timestamp); + + // Perform the permit op & ensure it's valid + vm.expectRevert(InvalidSigner.selector); + fraktionTokens.permitAllTransfer(address(1), contentOwner, block.timestamp, v, r, s); + } + + function test_permitTransferAll_InvalidNonce_ko() public { + // Generate signature + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + userPrivKey, + keccak256( + abi.encodePacked( + "\x19\x01", + fraktionTokens.getDomainSeperator(), + keccak256( + abi.encode(PERMIT_TRANSFER_ALL_TYPEHASH, user, contentOwner, 1312, block.timestamp) + ) + ) + ) + ); + + // Perform the permit op & ensure it's valid + vm.expectRevert(InvalidSigner.selector); + fraktionTokens.permitAllTransfer(user, contentOwner, block.timestamp, v, r, s); + } + + /* -------------------------------------------------------------------------- */ + /* Test transfer all */ + /* -------------------------------------------------------------------------- */ + + function test_transferAllFrom_ok() public { + // A few fraktion to the users + vm.startPrank(deployer); + fraktionTokens.mint(user, contentId.commonFraktionId(), 5); + fraktionTokens.mint(user, contentId.premiumFraktionId(), 2); + fraktionTokens.mint(user, contentId.goldFraktionId(), 1); + vm.stopPrank(); + + // Assert the fraktion is minted + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.commonFraktionId())), 5); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.premiumFraktionId())), 2); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.goldFraktionId())), 1); + + // Ask to transfer all of the premium fraktion + uint256[] memory ids = new uint256[](1); + ids[0] = FraktionId.unwrap(contentId.premiumFraktionId()); + + // Transfer all of the premium fraktion + address targetUser = _newUser("targetUser"); + vm.prank(user); + fraktionTokens.transferAllFrom(user, targetUser, ids); + + // Ensure all the premium fraktion are transfered + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.premiumFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.premiumFraktionId())), 2); + + // Build the array with all the fraktion type + ids = new uint256[](4); + ids[0] = FraktionId.unwrap(contentId.commonFraktionId()); + ids[1] = FraktionId.unwrap(contentId.premiumFraktionId()); + ids[2] = FraktionId.unwrap(contentId.goldFraktionId()); + ids[3] = FraktionId.unwrap(contentId.diamondFraktionId()); + + // Transfer all of them + vm.prank(user); + fraktionTokens.transferAllFrom(user, targetUser, ids); + + // Ensure every fraktion type is well transfered + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.commonFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.premiumFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.goldFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.diamondFraktionId())), 0); + + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.commonFraktionId())), 5); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.premiumFraktionId())), 2); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.goldFraktionId())), 1); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.diamondFraktionId())), 0); + } + /* -------------------------------------------------------------------------- */ /* Some helper's */ /* -------------------------------------------------------------------------- */ From 99d67e051dbec25fa6c6f90341bafe082b3e48e5 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 16:28:39 +0200 Subject: [PATCH 06/16] =?UTF-8?q?=F0=9F=A7=AA=20Adding=20a=20few=20wallet?= =?UTF-8?q?=20migrator=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 18 ++- contracts/utils/PushPullReward.sol | 45 +++---- contracts/wallets/WalletMigrator.sol | 81 +++++++++--- test/fraktions/FraktionTokens.t.sol | 6 +- test/wallets/WalletMigrator.t.sol | 181 +++++++++++++++++++++++++++ 5 files changed, 279 insertions(+), 52 deletions(-) create mode 100644 test/wallets/WalletMigrator.t.sol diff --git a/.gas-snapshot b/.gas-snapshot index 59366b9..3e6fef6 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -24,7 +24,7 @@ FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11304244) FrakTeasuryWalletTest:test_transfer_NotMinter_ko() (gas: 17684) FrakTeasuryWalletTest:test_transfer_RewardTooLarge_ko() (gas: 20534) FrakTeasuryWalletTest:test_transfer_ok() (gas: 136061) -FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3554) +FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3434) FrakTokenTest:test_burn_ok() (gas: 53287) FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 2502575) FrakTokenTest:test_cap_ok() (gas: 10366) @@ -102,9 +102,9 @@ MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103656) MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208232) MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209435) MultiVestingWalletsTest:test_transfer_ok() (gas: 226427) -ReferralPoolTest:test_canBeDeployedAndInit_ok() (gas: 1692225) +ReferralPoolTest:test_canBeDeployedAndInit_ok() (gas: 1690025) ReferralPoolTest:test_initialize_InitTwice_ko() (gas: 17881) -RewarderConfigTest:test_canBeDeployedAndInit_ok() (gas: 2600249) +RewarderConfigTest:test_canBeDeployedAndInit_ok() (gas: 2597849) RewarderConfigTest:test_initialize_InitTwice_ko() (gas: 26774) RewarderConfigTest:test_updateContentBadge_BadgeTooLarge_ko() (gas: 20191) RewarderConfigTest:test_updateContentBadge_InvalidRole_ko() (gas: 17630) @@ -126,14 +126,20 @@ RewarderDirectPaymentTest:test_payUserDirectly_InvalidReward_ko() (gas: 88533) RewarderDirectPaymentTest:test_payUserDirectly_InvalidRole_ko() (gas: 79215) RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105700) RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212716) -RewarderTest:test_pay_FreeFraktion_ok() (gas: 191967) +RewarderTest:test_pay_FreeFraktion_ok() (gas: 191970) RewarderTest:test_pay_InvalidAddress_ko() (gas: 21620) RewarderTest:test_pay_InvalidArray_ko() (gas: 38041) RewarderTest:test_pay_InvalidContent_ko() (gas: 56871) RewarderTest:test_pay_InvalidRoles_ko() (gas: 21259) RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367557) RewarderTest:test_pay_PayedFraktions_TooMuchListenCounts_ko() (gas: 167427) -RewarderTest:test_pay_PayedFraktions_ok() (gas: 405423) +RewarderTest:test_pay_PayedFraktions_ok() (gas: 405426) RewarderTest:test_pay_TooLargeReward_ko() (gas: 231010) VestingWalletFactoryTest:test_canBeDeployedAndInit_ok() (gas: 2093328) -VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) \ No newline at end of file +VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) +WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359016) +WalletMigratorTest:test_claimAllFounds_ok() (gas: 359209) +WalletMigratorTest:test_migrateFrationsForUser_ok() (gas: 269080) +WalletMigratorTest:test_migrateFrations_ok() (gas: 269300) +WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144544) +WalletMigratorTest:test_migrateFrk_ok() (gas: 144740) \ No newline at end of file diff --git a/contracts/utils/PushPullReward.sol b/contracts/utils/PushPullReward.sol index de5f4a6..1ee9312 100644 --- a/contracts/utils/PushPullReward.sol +++ b/contracts/utils/PushPullReward.sol @@ -23,9 +23,6 @@ abstract contract PushPullReward is IPushPullReward, Initializable { /// @dev 'bytes4(keccak256(bytes("RewardTooLarge()")))' uint256 private constant _REWARD_TOO_LARGE_SELECTOR = 0x71009bf7; - /// @dev 'bytes4(keccak256(bytes("NoReward()")))' - uint256 private constant _NO_REWARD_SELECTOR = 0x6e992686; - /* -------------------------------------------------------------------------- */ /* Event's */ /* -------------------------------------------------------------------------- */ @@ -139,17 +136,15 @@ abstract contract PushPullReward is IPushPullReward, Initializable { mstore(0x20, _pendingRewards.slot) let rewardSlot := keccak256(0, 0x40) userAmount := sload(rewardSlot) - // Revert if no reward - if iszero(userAmount) { - mstore(0x00, _NO_REWARD_SELECTOR) - revert(0x1c, 0x04) + // Emit the witdraw event and reset balance if user amount is positive + if userAmount { + // Emit the witdraw event + mstore(0x00, userAmount) + mstore(0x20, 0) + log2(0, 0x40, _REWARD_WITHDRAWAD_EVENT_SELECTOR, user) + // Reset his reward + sstore(rewardSlot, 0) } - // Emit the witdraw event - mstore(0x00, userAmount) - mstore(0x20, 0) - log2(0, 0x40, _REWARD_WITHDRAWAD_EVENT_SELECTOR, user) - // Reset his reward - sstore(rewardSlot, 0) } // Perform the transfer of the founds token.safeTransfer(user, userAmount); @@ -209,11 +204,6 @@ abstract contract PushPullReward is IPushPullReward, Initializable { let feeRecipientSlot := keccak256(0, 0x40) // Get the current user pending reward let pendingReward := sload(rewardSlot) - // Revert if no reward - if iszero(pendingReward) { - mstore(0x00, _NO_REWARD_SELECTOR) - revert(0x1c, 0x04) - } // Compute the fee's amount switch eq(feeRecipient, user) case 1 { @@ -225,14 +215,17 @@ abstract contract PushPullReward is IPushPullReward, Initializable { feesAmount := div(mul(pendingReward, feePercent), 100) userAmount := sub(pendingReward, feesAmount) } - // Reset the user reward - sstore(rewardSlot, 0) - // Store the fee recipient reward (if any only) - if feesAmount { sstore(feeRecipientSlot, add(sload(feeRecipientSlot), feesAmount)) } - // Emit the witdraw event - mstore(0x00, userAmount) - mstore(0x20, feesAmount) - log2(0, 0x40, _REWARD_WITHDRAWAD_EVENT_SELECTOR, user) + // Emit the witdraw event and reset balance if user amount is positive + if userAmount { + // Reset his reward + sstore(rewardSlot, 0) + // Store the fee recipient reward (if any only) + if feesAmount { sstore(feeRecipientSlot, add(sload(feeRecipientSlot), feesAmount)) } + // Emit the witdraw event + mstore(0x00, userAmount) + mstore(0x20, feesAmount) + log2(0, 0x40, _REWARD_WITHDRAWAD_EVENT_SELECTOR, user) + } } // Perform the transfer of the founds token.safeTransfer(user, userAmount); diff --git a/contracts/wallets/WalletMigrator.sol b/contracts/wallets/WalletMigrator.sol index d91548a..e795324 100644 --- a/contracts/wallets/WalletMigrator.sol +++ b/contracts/wallets/WalletMigrator.sol @@ -46,7 +46,7 @@ contract WalletMigrator is Multicallable { } /* -------------------------------------------------------------------------- */ - /* Public migration functions */ + /* Claim functions */ /* -------------------------------------------------------------------------- */ /// @dev Claim all the founds for a user at once @@ -54,15 +54,45 @@ contract WalletMigrator is Multicallable { _claimAllFounds(msg.sender); } + /// @dev Claim all the founds for a user at once + function claimAllFounds(address user) public { + _claimAllFounds(user); + } + + /// @dev Claim all the founds for a user at once + function _claimAllFounds(address user) internal { + rewarderPool.withdrawFounds(user); + contentPool.withdrawFounds(user); + referralPool.withdrawFounds(user); + } + + /* -------------------------------------------------------------------------- */ + /* Frak migration functions */ + /* -------------------------------------------------------------------------- */ + /// @dev Migrate all the FRK of the current user to the `newWallet` function migrateFrk(address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { + _migrateFrk(msg.sender, newWallet, deadline, v, r, s); + } + + /// @dev Migrate all the FRK of the current user to the `newWallet` + function migrateFrk(address user, address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { + _migrateFrk(user, newWallet, deadline, v, r, s); + } + + /// @dev Migrate all the frk of the `user` to the `newWallet`, using EIP-2612 signature as approval + function _migrateFrk(address user, address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) internal { // We use the signature to allow the transfer all the FRK of the user - frkToken.permit(msg.sender, address(this), type(uint256).max, deadline, v, r, s); + frkToken.permit(user, address(this), type(uint256).max, deadline, v, r, s); // And finally, we transfer all the FRK of the user to the new wallet - address(frkToken).safeTransferFrom(msg.sender, newWallet, frkToken.balanceOf(msg.sender)); + address(frkToken).safeTransferFrom(user, newWallet, frkToken.balanceOf(user)); } + /* -------------------------------------------------------------------------- */ + /* Fraktions migration functions */ + /* -------------------------------------------------------------------------- */ + /// @dev Migrate all the fraktions to the `newWallet`at once function migrateFraktions( address newWallet, @@ -73,27 +103,46 @@ contract WalletMigrator is Multicallable { uint256[] calldata ids ) external + { + _migrateFraktions(msg.sender, newWallet, deadline, v, r, s, ids); + } + + /// @dev Migrate all the fraktions to the `newWallet`at once + function migrateFraktions( + address user, + address newWallet, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s, + uint256[] calldata ids + ) + external + { + _migrateFraktions(user, newWallet, deadline, v, r, s, ids); + } + + /// @dev Migrate all the fraktions to the `newWallet`at once + function _migrateFraktions( + address user, + address newWallet, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s, + uint256[] calldata ids + ) + internal { // We use the signature to allow the transfer all the FRK of the user - fraktionTokens.permitAllTransfer(msg.sender, address(this), deadline, v, r, s); + fraktionTokens.permitAllTransfer(user, address(this), deadline, v, r, s); // And finally, we transfer all the FRK of the user to the new wallet - fraktionTokens.transferAllFrom(msg.sender, newWallet, ids); + fraktionTokens.transferAllFrom(user, newWallet, ids); } /// @dev Send all the matic of the sender to the `newWallet` function migrateMatic(address newWallet) external { newWallet.safeTransferAllETH(); } - - /* -------------------------------------------------------------------------- */ - /* Internal migration functions */ - /* -------------------------------------------------------------------------- */ - - /// @dev Claim all the founds for a user at once - function _claimAllFounds(address user) internal { - rewarderPool.withdrawFounds(user); - contentPool.withdrawFounds(user); - referralPool.withdrawFounds(user); - } } diff --git a/test/fraktions/FraktionTokens.t.sol b/test/fraktions/FraktionTokens.t.sol index d0a8cad..162ca64 100644 --- a/test/fraktions/FraktionTokens.t.sol +++ b/test/fraktions/FraktionTokens.t.sol @@ -237,9 +237,7 @@ contract FraktionTokensTest is FrakTest { abi.encodePacked( "\x19\x01", fraktionTokens.getDomainSeperator(), - keccak256( - abi.encode(PERMIT_TRANSFER_ALL_TYPEHASH, user, contentOwner, 1312, block.timestamp) - ) + keccak256(abi.encode(PERMIT_TRANSFER_ALL_TYPEHASH, user, contentOwner, 1312, block.timestamp)) ) ) ); @@ -260,7 +258,7 @@ contract FraktionTokensTest is FrakTest { fraktionTokens.mint(user, contentId.premiumFraktionId(), 2); fraktionTokens.mint(user, contentId.goldFraktionId(), 1); vm.stopPrank(); - + // Assert the fraktion is minted assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.commonFraktionId())), 5); assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.premiumFraktionId())), 2); diff --git a/test/wallets/WalletMigrator.t.sol b/test/wallets/WalletMigrator.t.sol new file mode 100644 index 0000000..2f57fdf --- /dev/null +++ b/test/wallets/WalletMigrator.t.sol @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GNU GPLv3 +pragma solidity 0.8.21; + +import "forge-std/console.sol"; +import { FrakTest } from "../FrakTest.sol"; +import { NotAuthorized, InvalidAddress, NoReward, RewardTooLarge, InvalidArray } from "contracts/utils/FrakErrors.sol"; +import { FrakTreasuryWallet, NotEnoughTreasury } from "contracts/wallets/FrakTreasuryWallet.sol"; +import { WalletMigrator } from "contracts/wallets/WalletMigrator.sol"; +import { FraktionId } from "contracts/libs/FraktionId.sol"; +import { ContentId } from "contracts/libs/ContentId.sol"; + +/// @dev Testing methods on the WalletMigrator +contract WalletMigratorTest is FrakTest { + WalletMigrator walletMigrator; + address targetUser; + + function setUp() public { + _setupTests(); + + // The user that will receive the migration result + targetUser = _newUser("migrationTargetUser"); + + // Build the wallet migrator we will test + walletMigrator = new WalletMigrator( + address(frakToken), + address(fraktionTokens), + address(rewarder), + address(contentPool), + address(referralPool) + ); + } + + /* -------------------------------------------------------------------------- */ + /* Test claim all founds */ + /* -------------------------------------------------------------------------- */ + + function test_claimAllFounds_ok() public withUserReward { + vm.prank(user); + walletMigrator.claimAllFounds(); + + // Ensure all the reward as been claimed + _assertRewardClaimed(); + } + + function test_claimAllFoundsForUser_ok() public withUserReward { + walletMigrator.claimAllFounds(user); + + // Ensure all the reward as been claimed + _assertRewardClaimed(); + } + + function _assertRewardClaimed() internal { + assertGt(frakToken.balanceOf(user), 0); + assertEq(rewarder.getAvailableFounds(user), 0); + assertEq(contentPool.getAvailableFounds(user), 0); + assertEq(referralPool.getAvailableFounds(user), 0); + } + + /* -------------------------------------------------------------------------- */ + /* Test frak transfer */ + /* -------------------------------------------------------------------------- */ + + function test_migrateFrk_ok() public withFrk(user, 10 ether) { + // Generate the permit signature for the wallet migration + uint256 deadline = block.timestamp; + (uint8 v, bytes32 r, bytes32 s) = + _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); + + // Perform the migration + vm.prank(user); + walletMigrator.migrateFrk(targetUser, deadline, v, r, s); + + // Ensure all the frk are migrated + _assertFrkTransfered(10 ether); + } + + function test_migrateFrkForUser_ok() public withFrk(user, 10 ether) { + // Generate the permit signature for the wallet migration + uint256 deadline = block.timestamp; + (uint8 v, bytes32 r, bytes32 s) = + _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); + + // Perform the migration + walletMigrator.migrateFrk(user, targetUser, deadline, v, r, s); + + // Ensure all the frk are migrated + _assertFrkTransfered(10 ether); + } + + function _assertFrkTransfered(uint256 amount) internal { + assertEq(frakToken.balanceOf(targetUser), amount); + assertEq(frakToken.balanceOf(user), 0); + } + + /* -------------------------------------------------------------------------- */ + /* Test fraktion transfer */ + /* -------------------------------------------------------------------------- */ + + function test_migrateFrations_ok() public userWithAllFraktions { + // Generate the permit signature for the wallet migration + uint256 deadline = block.timestamp; + (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); + + // Perform the migration + vm.prank(user); + walletMigrator.migrateFraktions(targetUser, deadline, v, r, s, _allFraktionsIds()); + + // Ensure every fraktion type is well transfered + _assertFraktionTransfered(); + } + + function test_migrateFrationsForUser_ok() public userWithAllFraktions { + // Generate the permit signature for the wallet migration + uint256 deadline = block.timestamp; + (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); + + // Perform the migration + walletMigrator.migrateFraktions(user, targetUser, deadline, v, r, s, _allFraktionsIds()); + + // Ensure every fraktion type is well transfered + _assertFraktionTransfered(); + } + + /// @dev Check that every fraktion type is transfered + function _assertFraktionTransfered() internal { + // Ensure every fraktion type is well transfered + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.commonFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.premiumFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.goldFraktionId())), 0); + assertEq(fraktionTokens.balanceOf(user, FraktionId.unwrap(contentId.diamondFraktionId())), 0); + + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.commonFraktionId())), 5); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.premiumFraktionId())), 2); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.goldFraktionId())), 1); + assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.diamondFraktionId())), 1); + } + + /* -------------------------------------------------------------------------- */ + /* Internal helper functions */ + /* -------------------------------------------------------------------------- */ + + modifier withUserReward() { + vm.startPrank(deployer); + // Mint a few frak to the rewarder + frakToken.mint(address(rewarder), 100_000 ether); + + // Mint a fraktion to our user + fraktionTokens.mint(user, contentId.goldFraktionId(), 1); + + // Then pay it multiple time on this content + ContentId[] memory contentIds = new ContentId[](1); + contentIds[0] = contentId; + uint256[] memory listenCounts = new uint256[](1); + listenCounts[0] = 300; + rewarder.payUser(user, 1, contentIds, listenCounts); + rewarder.payUser(user, 1, contentIds, listenCounts); + rewarder.payUser(user, 1, contentIds, listenCounts); + rewarder.payUser(user, 1, contentIds, listenCounts); + vm.stopPrank(); + _; + } + + modifier userWithAllFraktions() { + // A few fraktion to the users + vm.startPrank(deployer); + fraktionTokens.mint(user, contentId.commonFraktionId(), 5); + fraktionTokens.mint(user, contentId.premiumFraktionId(), 2); + fraktionTokens.mint(user, contentId.goldFraktionId(), 1); + fraktionTokens.mint(user, contentId.diamondFraktionId(), 1); + vm.stopPrank(); + _; + } + + function _allFraktionsIds() internal view returns (uint256[] memory fraktionIds) { + fraktionIds = new uint256[](4); + fraktionIds[0] = FraktionId.unwrap(contentId.commonFraktionId()); + fraktionIds[1] = FraktionId.unwrap(contentId.premiumFraktionId()); + fraktionIds[2] = FraktionId.unwrap(contentId.goldFraktionId()); + fraktionIds[3] = FraktionId.unwrap(contentId.diamondFraktionId()); + } +} From 75956abe831f390d755b1ea7afd4c423cda04c6c Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 17:02:17 +0200 Subject: [PATCH 07/16] =?UTF-8?q?=F0=9F=A7=AA=20Adding=20more=20test=20and?= =?UTF-8?q?=20extract=20wallet=20migrator=20ABI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 14 ++-- contracts/wallets/WalletMigrator.sol | 11 +-- test/wallets/WalletMigrator.t.sol | 108 +++++++++++++++++++++++++-- wagmi.config.ts | 1 + 4 files changed, 112 insertions(+), 22 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 3e6fef6..67c503f 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -137,9 +137,11 @@ RewarderTest:test_pay_PayedFraktions_ok() (gas: 405426) RewarderTest:test_pay_TooLargeReward_ko() (gas: 231010) VestingWalletFactoryTest:test_canBeDeployedAndInit_ok() (gas: 2093328) VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) -WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359016) -WalletMigratorTest:test_claimAllFounds_ok() (gas: 359209) -WalletMigratorTest:test_migrateFrationsForUser_ok() (gas: 269080) -WalletMigratorTest:test_migrateFrations_ok() (gas: 269300) -WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144544) -WalletMigratorTest:test_migrateFrk_ok() (gas: 144740) \ No newline at end of file +WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359033) +WalletMigratorTest:test_claimAllFounds_ok() (gas: 359181) +WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634528) +WalletMigratorTest:test_fullMigration_ok() (gas: 633829) +WalletMigratorTest:test_migrateFrationsForUser_ok() (gas: 269269) +WalletMigratorTest:test_migrateFrations_ok() (gas: 269384) +WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144531) +WalletMigratorTest:test_migrateFrk_ok() (gas: 144728) \ No newline at end of file diff --git a/contracts/wallets/WalletMigrator.sol b/contracts/wallets/WalletMigrator.sol index e795324..c88c0b1 100644 --- a/contracts/wallets/WalletMigrator.sol +++ b/contracts/wallets/WalletMigrator.sol @@ -55,7 +55,7 @@ contract WalletMigrator is Multicallable { } /// @dev Claim all the founds for a user at once - function claimAllFounds(address user) public { + function claimAllFoundsForUser(address user) public { _claimAllFounds(user); } @@ -76,7 +76,7 @@ contract WalletMigrator is Multicallable { } /// @dev Migrate all the FRK of the current user to the `newWallet` - function migrateFrk(address user, address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { + function migrateFrkForUser(address user, address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { _migrateFrk(user, newWallet, deadline, v, r, s); } @@ -108,7 +108,7 @@ contract WalletMigrator is Multicallable { } /// @dev Migrate all the fraktions to the `newWallet`at once - function migrateFraktions( + function migrateFraktionsForUser( address user, address newWallet, uint256 deadline, @@ -140,9 +140,4 @@ contract WalletMigrator is Multicallable { // And finally, we transfer all the FRK of the user to the new wallet fraktionTokens.transferAllFrom(user, newWallet, ids); } - - /// @dev Send all the matic of the sender to the `newWallet` - function migrateMatic(address newWallet) external { - newWallet.safeTransferAllETH(); - } } diff --git a/test/wallets/WalletMigrator.t.sol b/test/wallets/WalletMigrator.t.sol index 2f57fdf..df42e38 100644 --- a/test/wallets/WalletMigrator.t.sol +++ b/test/wallets/WalletMigrator.t.sol @@ -39,18 +39,19 @@ contract WalletMigratorTest is FrakTest { walletMigrator.claimAllFounds(); // Ensure all the reward as been claimed + assertGt(frakToken.balanceOf(user), 0); _assertRewardClaimed(); } function test_claimAllFoundsForUser_ok() public withUserReward { - walletMigrator.claimAllFounds(user); + walletMigrator.claimAllFoundsForUser(user); // Ensure all the reward as been claimed + assertGt(frakToken.balanceOf(user), 0); _assertRewardClaimed(); } function _assertRewardClaimed() internal { - assertGt(frakToken.balanceOf(user), 0); assertEq(rewarder.getAvailableFounds(user), 0); assertEq(contentPool.getAvailableFounds(user), 0); assertEq(referralPool.getAvailableFounds(user), 0); @@ -81,7 +82,7 @@ contract WalletMigratorTest is FrakTest { _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); // Perform the migration - walletMigrator.migrateFrk(user, targetUser, deadline, v, r, s); + walletMigrator.migrateFrkForUser(user, targetUser, deadline, v, r, s); // Ensure all the frk are migrated _assertFrkTransfered(10 ether); @@ -96,7 +97,7 @@ contract WalletMigratorTest is FrakTest { /* Test fraktion transfer */ /* -------------------------------------------------------------------------- */ - function test_migrateFrations_ok() public userWithAllFraktions { + function test_migrateFrations_ok() public withUserFraktions { // Generate the permit signature for the wallet migration uint256 deadline = block.timestamp; (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); @@ -109,13 +110,13 @@ contract WalletMigratorTest is FrakTest { _assertFraktionTransfered(); } - function test_migrateFrationsForUser_ok() public userWithAllFraktions { + function test_migrateFrationsForUser_ok() public withUserFraktions { // Generate the permit signature for the wallet migration uint256 deadline = block.timestamp; (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); // Perform the migration - walletMigrator.migrateFraktions(user, targetUser, deadline, v, r, s, _allFraktionsIds()); + walletMigrator.migrateFraktionsForUser(user, targetUser, deadline, v, r, s, _allFraktionsIds()); // Ensure every fraktion type is well transfered _assertFraktionTransfered(); @@ -131,10 +132,101 @@ contract WalletMigratorTest is FrakTest { assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.commonFraktionId())), 5); assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.premiumFraktionId())), 2); - assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.goldFraktionId())), 1); + assertAlmostEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.goldFraktionId())), 1, 1); assertEq(fraktionTokens.balanceOf(targetUser, FraktionId.unwrap(contentId.diamondFraktionId())), 1); } + /* -------------------------------------------------------------------------- */ + /* Test full migration */ + /* -------------------------------------------------------------------------- */ + + function test_fullMigration_ok() public withUserReward withFrk(user, 10 ether) withUserFraktions { + bytes[] memory migrationCallData = new bytes[](3); + + // Build the claim function data + migrationCallData[0] = abi.encodeWithSelector(WalletMigrator.claimAllFounds.selector); + + // Generate signature for frk transfer & encode function data + uint256 deadline = block.timestamp; + (uint8 v, bytes32 r, bytes32 s) = + _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); + migrationCallData[1] = abi.encodeWithSelector( + WalletMigrator.migrateFrk.selector, + targetUser, + deadline, + v, + r, + s + ); + + // Generate signature for fraktion transfer & encode function data + (v, r, s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); + migrationCallData[2] = abi.encodeWithSelector( + WalletMigrator.migrateFraktions.selector, + targetUser, + deadline, + v, + r, + s, + _allFraktionsIds() + ); + + // Perform the multicall + vm.prank(user); + walletMigrator.multicall(migrationCallData); + + // Ensure the user has no frk remaining + assertEq(frakToken.balanceOf(user), 0); + + // Ensure the user has no more reward and fraktions + _assertRewardClaimed(); + _assertFraktionTransfered(); + } + + function test_fullMigrationForUser_ok() public withUserReward withFrk(user, 10 ether) withUserFraktions { + bytes[] memory migrationCallData = new bytes[](3); + + // Build the claim function data + migrationCallData[0] = abi.encodeWithSelector(WalletMigrator.claimAllFoundsForUser.selector, user); + + // Generate signature for frk transfer & encode function data + uint256 deadline = block.timestamp; + (uint8 v, bytes32 r, bytes32 s) = + _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); + migrationCallData[1] = abi.encodeWithSelector( + WalletMigrator.migrateFrkForUser.selector, + user, + targetUser, + deadline, + v, + r, + s + ); + + // Generate signature for fraktion transfer & encode function data + (v, r, s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); + migrationCallData[2] = abi.encodeWithSelector( + WalletMigrator.migrateFraktionsForUser.selector, + user, + targetUser, + deadline, + v, + r, + s, + _allFraktionsIds() + ); + + // Perform the multicall + walletMigrator.multicall(migrationCallData); + + // Ensure the user has no frk remaining + assertEq(frakToken.balanceOf(user), 0); + + // Ensure the user has no more reward and fraktions + _assertRewardClaimed(); + _assertFraktionTransfered(); + } + /* -------------------------------------------------------------------------- */ /* Internal helper functions */ /* -------------------------------------------------------------------------- */ @@ -160,7 +252,7 @@ contract WalletMigratorTest is FrakTest { _; } - modifier userWithAllFraktions() { + modifier withUserFraktions() { // A few fraktion to the users vm.startPrank(deployer); fraktionTokens.mint(user, contentId.commonFraktionId(), 5); diff --git a/wagmi.config.ts b/wagmi.config.ts index d19dcb6..72e2bfa 100644 --- a/wagmi.config.ts +++ b/wagmi.config.ts @@ -21,6 +21,7 @@ export default defineConfig({ 'PushPullReward.json', 'ReferralPool.json', 'Rewarder.json', + 'WalletMigrator.json', 'MonoPool.json' ] }), From e9c8ad95125f52468e76f5978f79ace3e3487ed0 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 17:08:10 +0200 Subject: [PATCH 08/16] =?UTF-8?q?=F0=9F=97=83=EF=B8=8F=20Switch=20FrkToken?= =?UTF-8?q?=20to=20eip712=20diamond=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/storage-check.yml | 12 ++-- contracts/tokens/EIP712Base.sol | 87 ---------------------------- contracts/tokens/FrakToken.sol | 6 +- contracts/utils/EIP712Diamond.sol | 3 +- contracts/wallets/WalletMigrator.sol | 11 +++- test/wallets/WalletMigrator.t.sol | 41 +++---------- 6 files changed, 28 insertions(+), 132 deletions(-) delete mode 100644 contracts/tokens/EIP712Base.sol diff --git a/.github/workflows/storage-check.yml b/.github/workflows/storage-check.yml index 2298acf..9ad48b7 100644 --- a/.github/workflows/storage-check.yml +++ b/.github/workflows/storage-check.yml @@ -58,7 +58,7 @@ jobs: key: foundry-${{ github.repository_id }}-${{ hashFiles('foundry.toml') }} - name: '🧪 Check FRK Token storage' - uses: Rubilmax/foundry-storage-check@v3.5 + uses: Rubilmax/foundry-storage-check@v3.6 with: contract: contracts/tokens/FrakToken.sol:FrakToken rpcUrl: ${{ env.POLYGON_RPC_URL }} @@ -66,7 +66,7 @@ jobs: failOnRemoval: true - name: '🧪 Check Fraktion Token storage' - uses: Rubilmax/foundry-storage-check@v3.5 + uses: Rubilmax/foundry-storage-check@v3.6 with: contract: contracts/fraktions/FraktionTokens.sol:FraktionTokens rpcUrl: ${{ env.POLYGON_RPC_URL }} @@ -74,7 +74,7 @@ jobs: failOnRemoval: true - name: '🧪 Check content pool storage' - uses: Rubilmax/foundry-storage-check@v3.5 + uses: Rubilmax/foundry-storage-check@v3.6 with: contract: contracts/reward/contentPool/ContentPool.sol:ContentPool rpcUrl: ${{ env.POLYGON_RPC_URL }} @@ -82,7 +82,7 @@ jobs: failOnRemoval: true - name: '🧪 Check referral pool storage' - uses: Rubilmax/foundry-storage-check@v3.5 + uses: Rubilmax/foundry-storage-check@v3.6 with: contract: contracts/reward/referralPool/ReferralPool.sol:ReferralPool rpcUrl: ${{ env.POLYGON_RPC_URL }} @@ -90,7 +90,7 @@ jobs: failOnRemoval: true - name: '🧪 Check rewarder storage' - uses: Rubilmax/foundry-storage-check@v3.5 + uses: Rubilmax/foundry-storage-check@v3.6 with: contract: contracts/reward/Rewarder.sol:Rewarder rpcUrl: ${{ env.POLYGON_RPC_URL }} @@ -98,7 +98,7 @@ jobs: failOnRemoval: true - name: '🧪 Check minter storage' - uses: Rubilmax/foundry-storage-check@v3.5 + uses: Rubilmax/foundry-storage-check@v3.6 with: contract: contracts/minter/Minter.sol:Minter rpcUrl: ${{ env.POLYGON_RPC_URL }} diff --git a/contracts/tokens/EIP712Base.sol b/contracts/tokens/EIP712Base.sol deleted file mode 100644 index 6580ea9..0000000 --- a/contracts/tokens/EIP712Base.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GNU GPLv3 -pragma solidity 0.8.21; - -import { Initializable } from "@oz-upgradeable/proxy/utils/Initializable.sol"; - -contract EIP712Base is Initializable { - struct EIP712Domain { - string name; - string version; - address verifyingContract; - bytes32 salt; - } - - /* -------------------------------------------------------------------------- */ - /* Constant's */ - /* -------------------------------------------------------------------------- */ - - string internal constant ERC712_VERSION = "1"; - - bytes32 internal constant EIP712_DOMAIN_TYPEHASH = - keccak256(bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")); - - /* -------------------------------------------------------------------------- */ - /* Storage */ - /* -------------------------------------------------------------------------- */ - - /// @dev The current domain seperator - bytes32 internal domainSeperator; - - /// @dev Nonces per user - mapping(address user => uint256 nonces) internal nonces; - - /// @dev init function - function _initializeEIP712(string memory name) internal onlyInitializing { - _setDomainSeperator(name); - } - - /* -------------------------------------------------------------------------- */ - /* Public view method */ - /* -------------------------------------------------------------------------- */ - - /// @dev Current domain seperator - function getDomainSeperator() public view returns (bytes32) { - return domainSeperator; - } - - /// @dev Get the current 'nonce' for the given 'user' - function getNonce(address user) external view returns (uint256 nonce) { - nonce = nonces[user]; - } - - /* -------------------------------------------------------------------------- */ - /* Internal function's */ - /* -------------------------------------------------------------------------- */ - - function _setDomainSeperator(string memory name) internal { - domainSeperator = keccak256( - abi.encode( - EIP712_DOMAIN_TYPEHASH, - keccak256(bytes(name)), - keccak256(bytes(ERC712_VERSION)), - block.chainid, - address(this) - ) - ); - } - - /** - * Accept message hash and returns hash message in EIP712 compatible form - * So that it can be used to recover signer from signature signed using EIP712 formatted data - * https://eips.ethereum.org/EIPS/eip-712 - * "\\x19" makes the encoding deterministic - * "\\x01" is the version byte to make it compatible to EIP-191 - */ - function toTypedMessageHash(bytes32 messageHash) internal view returns (bytes32 digest) { - bytes32 separator = domainSeperator; - assembly { - // Compute the digest. - mstore(0x00, 0x1901000000000000) // Store "\x19\x01". - mstore(0x1a, separator) // Store the domain separator. - mstore(0x3a, messageHash) // Store the message hash. - digest := keccak256(0x18, 0x42) - // Restore the part of the free memory slot that was overwritten. - mstore(0x3a, 0) - } - } -} diff --git a/contracts/tokens/FrakToken.sol b/contracts/tokens/FrakToken.sol index 18a7953..9865822 100644 --- a/contracts/tokens/FrakToken.sol +++ b/contracts/tokens/FrakToken.sol @@ -6,7 +6,7 @@ import { FrakRoles } from "../roles/FrakRoles.sol"; import { InvalidSigner } from "../utils/FrakErrors.sol"; import { FrakAccessControlUpgradeable } from "../roles/FrakAccessControlUpgradeable.sol"; import { IFrakToken } from "./IFrakToken.sol"; -import { EIP712Base } from "./EIP712Base.sol"; +import { EIP712Diamond } from "../utils/EIP712Diamond.sol"; import { ECDSA } from "solady/utils/ECDSA.sol"; /// @author @KONFeature @@ -14,7 +14,7 @@ import { ECDSA } from "solady/utils/ECDSA.sol"; /// @notice ERC20 Contract for the FRAK token /// @dev Compliant with ERC20 - EIP712 - EIP2612 /// @custom:security-contact contact@frak.id -contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Base, IFrakToken { +contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Diamond, IFrakToken { /* -------------------------------------------------------------------------- */ /* Constant's */ /* -------------------------------------------------------------------------- */ @@ -104,7 +104,7 @@ contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Base owner, spender, value, - nonces[owner]++, + useNonce(owner), deadline ) ) diff --git a/contracts/utils/EIP712Diamond.sol b/contracts/utils/EIP712Diamond.sol index 0c9466d..15f07d4 100644 --- a/contracts/utils/EIP712Diamond.sol +++ b/contracts/utils/EIP712Diamond.sol @@ -20,7 +20,8 @@ contract EIP712Diamond { /* Constant's */ /* -------------------------------------------------------------------------- */ - string internal constant ERC712_VERSION = "1"; + /// @dev The current version of the erc712, 2 since we switch between inline storage to diamond storage + string internal constant ERC712_VERSION = "2"; bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")); diff --git a/contracts/wallets/WalletMigrator.sol b/contracts/wallets/WalletMigrator.sol index c88c0b1..3f2650c 100644 --- a/contracts/wallets/WalletMigrator.sol +++ b/contracts/wallets/WalletMigrator.sol @@ -76,7 +76,16 @@ contract WalletMigrator is Multicallable { } /// @dev Migrate all the FRK of the current user to the `newWallet` - function migrateFrkForUser(address user, address newWallet, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external { + function migrateFrkForUser( + address user, + address newWallet, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) + external + { _migrateFrk(user, newWallet, deadline, v, r, s); } diff --git a/test/wallets/WalletMigrator.t.sol b/test/wallets/WalletMigrator.t.sol index df42e38..39b98a3 100644 --- a/test/wallets/WalletMigrator.t.sol +++ b/test/wallets/WalletMigrator.t.sol @@ -150,31 +150,18 @@ contract WalletMigratorTest is FrakTest { uint256 deadline = block.timestamp; (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); - migrationCallData[1] = abi.encodeWithSelector( - WalletMigrator.migrateFrk.selector, - targetUser, - deadline, - v, - r, - s - ); + migrationCallData[1] = abi.encodeWithSelector(WalletMigrator.migrateFrk.selector, targetUser, deadline, v, r, s); // Generate signature for fraktion transfer & encode function data (v, r, s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); migrationCallData[2] = abi.encodeWithSelector( - WalletMigrator.migrateFraktions.selector, - targetUser, - deadline, - v, - r, - s, - _allFraktionsIds() + WalletMigrator.migrateFraktions.selector, targetUser, deadline, v, r, s, _allFraktionsIds() ); // Perform the multicall vm.prank(user); walletMigrator.multicall(migrationCallData); - + // Ensure the user has no frk remaining assertEq(frakToken.balanceOf(user), 0); @@ -193,32 +180,18 @@ contract WalletMigratorTest is FrakTest { uint256 deadline = block.timestamp; (uint8 v, bytes32 r, bytes32 s) = _generateUserPermitSignature(address(walletMigrator), type(uint256).max, deadline); - migrationCallData[1] = abi.encodeWithSelector( - WalletMigrator.migrateFrkForUser.selector, - user, - targetUser, - deadline, - v, - r, - s - ); + migrationCallData[1] = + abi.encodeWithSelector(WalletMigrator.migrateFrkForUser.selector, user, targetUser, deadline, v, r, s); // Generate signature for fraktion transfer & encode function data (v, r, s) = _generateUserPermitTransferAllSignature(address(walletMigrator), deadline); migrationCallData[2] = abi.encodeWithSelector( - WalletMigrator.migrateFraktionsForUser.selector, - user, - targetUser, - deadline, - v, - r, - s, - _allFraktionsIds() + WalletMigrator.migrateFraktionsForUser.selector, user, targetUser, deadline, v, r, s, _allFraktionsIds() ); // Perform the multicall walletMigrator.multicall(migrationCallData); - + // Ensure the user has no frk remaining assertEq(frakToken.balanceOf(user), 0); From 4c585770c9663ab2417449943209f85227110334 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 17:23:23 +0200 Subject: [PATCH 09/16] =?UTF-8?q?=F0=9F=90=9B=20Test=20fix=20storage=20lay?= =?UTF-8?q?out=20for=20FrkToken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/tokens/FrakToken.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/tokens/FrakToken.sol b/contracts/tokens/FrakToken.sol index 9865822..dec4b8a 100644 --- a/contracts/tokens/FrakToken.sol +++ b/contracts/tokens/FrakToken.sol @@ -26,6 +26,11 @@ contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Diam /* Custom error's */ /* -------------------------------------------------------------------------- */ + /// @dev Gap variable for the previous domain separator variable from the EIP712 Base contract + bytes32 private _gapOldDomainSeparator; + /// @dev Gap variable for the previous nonce variable from the EIP712 Base contract + mapping(address => uint256) private _gapOldNonces; + /// @dev 'bytes4(keccak256(bytes("PermitDelayExpired()")))' uint256 private constant _PERMIT_DELAYED_EXPIRED_SELECTOR = 0x95fc6e60; From d0ab8e0be3849e53f725276f201ba5992852402a Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 17:32:34 +0200 Subject: [PATCH 10/16] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Update=20gas=20snaps?= =?UTF-8?q?hot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 134 +++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 67c503f..62e9ab8 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -5,40 +5,40 @@ ContentPoolTest:test_canBeDeployedAndInit_ok() (gas: 2820972) ContentPoolTest:test_getRewardStates_ok() (gas: 223662) ContentPoolTest:test_initialize_InitTwice_ko() (gas: 17982) ContentPoolTest:test_participantStates_ok() (gas: 220752) -ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428687) -ContentPoolTest:test_updateUserAndPool_ok() (gas: 325494) -ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539500) -ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713307) -ContentPoolTest:test_updateUser_ok() (gas: 400284) +ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428734) +ContentPoolTest:test_updateUserAndPool_ok() (gas: 325496) +ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539524) +ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713328) +ContentPoolTest:test_updateUser_ok() (gas: 400285) FrakTeasuryWalletTest:test_canBeDeployedAndInit_ok() (gas: 1773426) FrakTeasuryWalletTest:test_initialize_InitTwice_ko() (gas: 17937) FrakTeasuryWalletTest:test_transferBatch_InvalidArray_ko() (gas: 28753) -FrakTeasuryWalletTest:test_transferBatch_NoReward_ko() (gas: 34416) -FrakTeasuryWalletTest:test_transferBatch_NotEnoughTreasury_ko() (gas: 11305534) +FrakTeasuryWalletTest:test_transferBatch_NoReward_ko() (gas: 34394) +FrakTeasuryWalletTest:test_transferBatch_NotEnoughTreasury_ko() (gas: 11334820) FrakTeasuryWalletTest:test_transferBatch_NotMinter_ko() (gas: 18928) -FrakTeasuryWalletTest:test_transferBatch_RewardTooLarge_ko() (gas: 34431) -FrakTeasuryWalletTest:test_transferBatch_ok() (gas: 137823) +FrakTeasuryWalletTest:test_transferBatch_RewardTooLarge_ko() (gas: 34409) +FrakTeasuryWalletTest:test_transferBatch_ok() (gas: 137867) FrakTeasuryWalletTest:test_transfer_InvalidAddress_ko() (gas: 18375) FrakTeasuryWalletTest:test_transfer_NoReward_ko() (gas: 20508) -FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11304244) +FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11333531) FrakTeasuryWalletTest:test_transfer_NotMinter_ko() (gas: 17684) FrakTeasuryWalletTest:test_transfer_RewardTooLarge_ko() (gas: 20534) -FrakTeasuryWalletTest:test_transfer_ok() (gas: 136061) -FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3434) -FrakTokenTest:test_burn_ok() (gas: 53287) -FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 2502575) +FrakTeasuryWalletTest:test_transfer_ok() (gas: 136105) +FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3375) +FrakTokenTest:test_burn_ok() (gas: 53304) +FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 2537901) FrakTokenTest:test_cap_ok() (gas: 10366) FrakTokenTest:test_decimals_ok() (gas: 10426) -FrakTokenTest:test_initialize_InitTwice_ko() (gas: 15759) -FrakTokenTest:test_mint_CapExceed_ko() (gas: 88106) -FrakTokenTest:test_mint_InvalidRole_ko() (gas: 17639) -FrakTokenTest:test_mint_ok() (gas: 68154) +FrakTokenTest:test_initialize_InitTwice_ko() (gas: 15737) +FrakTokenTest:test_mint_CapExceed_ko() (gas: 88431) +FrakTokenTest:test_mint_InvalidRole_ko() (gas: 17704) +FrakTokenTest:test_mint_ok() (gas: 68197) FrakTokenTest:test_name_ok() (gas: 14776) -FrakTokenTest:test_permit_DelayExpired_ko() (gas: 28091) -FrakTokenTest:test_permit_InvalidNonce_ko() (gas: 50226) -FrakTokenTest:test_permit_InvalidSigner_ko() (gas: 53835) -FrakTokenTest:test_permit_ok() (gas: 77672) -FrakTokenTest:test_symbol_ok() (gas: 14797) +FrakTokenTest:test_permit_DelayExpired_ko() (gas: 28069) +FrakTokenTest:test_permit_InvalidNonce_ko() (gas: 50313) +FrakTokenTest:test_permit_InvalidSigner_ko() (gas: 53922) +FrakTokenTest:test_permit_ok() (gas: 77759) +FrakTokenTest:test_symbol_ok() (gas: 14775) FraktionCostBadgesTest:test_defaultPrice_InvalidFraktionType_ko() (gas: 46597) FraktionCostBadgesTest:test_defaultPrice_ok() (gas: 26214) FraktionCostBadgesTest:test_updatePrice_InvalidFraktionType_ko() (gas: 46266) @@ -69,39 +69,39 @@ MinterTest:test_canBeDeployedAndInit_ok() (gas: 2267698) MinterTest:test_increaseSupply_InvalidRole_ko() (gas: 62382) MinterTest:test_increaseSupply_ok() (gas: 75937) MinterTest:test_initialize_InitTwice_ko() (gas: 22408) -MinterTest:test_mintFraktionForUser_ok() (gas: 212738) -MinterTest:test_mintFraktion_TooManyFraktion_ko() (gas: 216261) -MinterTest:test_mintFraktion_ok() (gas: 210197) +MinterTest:test_mintFraktionForUser_ok() (gas: 212890) +MinterTest:test_mintFraktion_TooManyFraktion_ko() (gas: 216413) +MinterTest:test_mintFraktion_ok() (gas: 210349) MinterTest:test_mintFreeFraktionForUser_ok() (gas: 60215) MinterTest:test_mintFreeFraktion_ExpectingOnlyFreeFraktion_ko() (gas: 40161) MinterTest:test_mintFreeFraktion_TooManyFraktion_ko() (gas: 66109) MinterTest:test_mintFreeFraktion_ok() (gas: 62919) MultiVestingWalletsTest:test_canBeDeployedAndInit_ok() (gas: 2732546) -MultiVestingWalletsTest:test_createVestBatch() (gas: 210700) -MultiVestingWalletsTest:test_createVestBatch_ArrayInvalidLength_ko() (gas: 79027) -MultiVestingWalletsTest:test_createVestBatch_EmptyArray_ko() (gas: 78827) -MultiVestingWalletsTest:test_createVestBatch_NotEnoughReserve_ko() (gas: 85446) -MultiVestingWalletsTest:test_createVestBatch_NotManager_ko() (gas: 80864) -MultiVestingWalletsTest:test_createVest_InvalidAddress_ko() (gas: 81908) -MultiVestingWalletsTest:test_createVest_InvalidDuration_ko() (gas: 80450) -MultiVestingWalletsTest:test_createVest_InvalidReward_ko() (gas: 81932) -MultiVestingWalletsTest:test_createVest_InvalidStartDateTooFar_ko() (gas: 80459) -MultiVestingWalletsTest:test_createVest_InvalidStartDate_ko() (gas: 80499) -MultiVestingWalletsTest:test_createVest_NotEnoughReserve_ko() (gas: 84011) -MultiVestingWalletsTest:test_createVest_NotManager_ko() (gas: 79610) -MultiVestingWalletsTest:test_createVest_TooLargeReward_ko() (gas: 82001) -MultiVestingWalletsTest:test_createVest_ok() (gas: 209020) +MultiVestingWalletsTest:test_createVestBatch() (gas: 210743) +MultiVestingWalletsTest:test_createVestBatch_ArrayInvalidLength_ko() (gas: 79092) +MultiVestingWalletsTest:test_createVestBatch_EmptyArray_ko() (gas: 78892) +MultiVestingWalletsTest:test_createVestBatch_NotEnoughReserve_ko() (gas: 85489) +MultiVestingWalletsTest:test_createVestBatch_NotManager_ko() (gas: 80929) +MultiVestingWalletsTest:test_createVest_InvalidAddress_ko() (gas: 81951) +MultiVestingWalletsTest:test_createVest_InvalidDuration_ko() (gas: 80515) +MultiVestingWalletsTest:test_createVest_InvalidReward_ko() (gas: 81975) +MultiVestingWalletsTest:test_createVest_InvalidStartDateTooFar_ko() (gas: 80524) +MultiVestingWalletsTest:test_createVest_InvalidStartDate_ko() (gas: 80564) +MultiVestingWalletsTest:test_createVest_NotEnoughReserve_ko() (gas: 84054) +MultiVestingWalletsTest:test_createVest_NotManager_ko() (gas: 79675) +MultiVestingWalletsTest:test_createVest_TooLargeReward_ko() (gas: 82044) +MultiVestingWalletsTest:test_createVest_ok() (gas: 209063) MultiVestingWalletsTest:test_decimals_ok() (gas: 10391) MultiVestingWalletsTest:test_initialize_InitTwice_ko() (gas: 18027) MultiVestingWalletsTest:test_name_ok() (gas: 12085) -MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233561) -MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228498) -MultiVestingWalletsTest:test_release_ok() (gas: 237964) +MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233627) +MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228564) +MultiVestingWalletsTest:test_release_ok() (gas: 238030) MultiVestingWalletsTest:test_symbol_ok() (gas: 12117) -MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103656) -MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208232) -MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209435) -MultiVestingWalletsTest:test_transfer_ok() (gas: 226427) +MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103634) +MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208275) +MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209478) +MultiVestingWalletsTest:test_transfer_ok() (gas: 226470) ReferralPoolTest:test_canBeDeployedAndInit_ok() (gas: 1690025) ReferralPoolTest:test_initialize_InitTwice_ko() (gas: 17881) RewarderConfigTest:test_canBeDeployedAndInit_ok() (gas: 2597849) @@ -114,34 +114,34 @@ RewarderConfigTest:test_updateListenerBadge_InvalidRole_ko() (gas: 17711) RewarderConfigTest:test_updateListenerBadge_ok() (gas: 46543) RewarderConfigTest:test_updateTpu_InvalidRole_ko() (gas: 15412) RewarderConfigTest:test_updateTpu_ok() (gas: 23775) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139378) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_EmptyAmount_ko() (gas: 81286) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidArray_ko() (gas: 79510) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidRole_ko() (gas: 80397) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeAmount_ko() (gas: 81344) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeArray_ko() (gas: 82833) -RewarderDirectPaymentTest:test_payUserDirectly() (gas: 111195) -RewarderDirectPaymentTest:test_payUserDirectly_InvalidAddress_ko() (gas: 77885) -RewarderDirectPaymentTest:test_payUserDirectly_InvalidReward_ko() (gas: 88533) -RewarderDirectPaymentTest:test_payUserDirectly_InvalidRole_ko() (gas: 79215) -RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105700) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139443) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_EmptyAmount_ko() (gas: 81351) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidArray_ko() (gas: 79575) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidRole_ko() (gas: 80462) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeAmount_ko() (gas: 81409) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeArray_ko() (gas: 82898) +RewarderDirectPaymentTest:test_payUserDirectly() (gas: 111283) +RewarderDirectPaymentTest:test_payUserDirectly_InvalidAddress_ko() (gas: 77950) +RewarderDirectPaymentTest:test_payUserDirectly_InvalidReward_ko() (gas: 88598) +RewarderDirectPaymentTest:test_payUserDirectly_InvalidRole_ko() (gas: 79280) +RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105810) RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212716) -RewarderTest:test_pay_FreeFraktion_ok() (gas: 191970) +RewarderTest:test_pay_FreeFraktion_ok() (gas: 191971) RewarderTest:test_pay_InvalidAddress_ko() (gas: 21620) RewarderTest:test_pay_InvalidArray_ko() (gas: 38041) RewarderTest:test_pay_InvalidContent_ko() (gas: 56871) RewarderTest:test_pay_InvalidRoles_ko() (gas: 21259) -RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367557) +RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367580) RewarderTest:test_pay_PayedFraktions_TooMuchListenCounts_ko() (gas: 167427) -RewarderTest:test_pay_PayedFraktions_ok() (gas: 405426) +RewarderTest:test_pay_PayedFraktions_ok() (gas: 405472) RewarderTest:test_pay_TooLargeReward_ko() (gas: 231010) VestingWalletFactoryTest:test_canBeDeployedAndInit_ok() (gas: 2093328) VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) -WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359033) -WalletMigratorTest:test_claimAllFounds_ok() (gas: 359181) -WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634528) -WalletMigratorTest:test_fullMigration_ok() (gas: 633829) +WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359166) +WalletMigratorTest:test_claimAllFounds_ok() (gas: 359314) +WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634791) +WalletMigratorTest:test_fullMigration_ok() (gas: 634092) WalletMigratorTest:test_migrateFrationsForUser_ok() (gas: 269269) WalletMigratorTest:test_migrateFrations_ok() (gas: 269384) -WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144531) -WalletMigratorTest:test_migrateFrk_ok() (gas: 144728) \ No newline at end of file +WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144617) +WalletMigratorTest:test_migrateFrk_ok() (gas: 144814) \ No newline at end of file From 51a170184b07f266db66f8e09eba35496602e451 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Thu, 19 Oct 2023 18:06:02 +0200 Subject: [PATCH 11/16] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20a=20few=20typo?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/libs/ContentId.sol | 4 ++-- contracts/minter/IMinter.sol | 4 ++-- contracts/minter/Minter.sol | 8 ++++---- contracts/minter/badges/FraktionCostBadges.sol | 10 +++++----- contracts/reward/IRewarder.sol | 6 +++--- contracts/reward/Rewarder.sol | 16 ++++++++-------- contracts/reward/contentPool/ContentPool.sol | 14 +++++++------- contracts/reward/contentPool/IContentPool.sol | 10 +++++----- contracts/roles/FrakAccessControlUpgradeable.sol | 14 +++++++------- contracts/tokens/FrakToken.sol | 6 +++--- contracts/utils/EIP712Diamond.sol | 2 +- contracts/utils/IPushPullReward.sol | 6 +++--- contracts/utils/PushPullReward.sol | 10 +++++----- contracts/wallets/FrakTreasuryWallet.sol | 6 +++--- contracts/wallets/MultiVestingWallets.sol | 2 +- script/utils/UpgradeScript.s.sol | 4 ++-- test/fraktions/FraktionTokens.t.sol | 8 ++++---- test/minter/Minter.t.sol | 8 ++++---- test/reward/RewarderConfig.t.sol | 2 +- test/reward/pools/ContentPool.t.sol | 4 ++-- test/reward/pools/ReferralPool.t.sol | 2 +- test/tokens/FrakToken.t.sol | 4 ++-- test/wallets/FrakTeasuryWallet.t.sol | 4 ++-- test/wallets/MultiVestingWallets.t.sol | 4 ++-- test/wallets/VestingWalletFactory.t.sol | 2 +- 25 files changed, 80 insertions(+), 80 deletions(-) diff --git a/contracts/libs/ContentId.sol b/contracts/libs/ContentId.sol index 93a8873..928b702 100644 --- a/contracts/libs/ContentId.sol +++ b/contracts/libs/ContentId.sol @@ -15,7 +15,7 @@ using ContentIdLib for ContentId global; /// @custom:security-contact contact@frak.id library ContentIdLib { /* -------------------------------------------------------------------------- */ - /* Constant's */ + /* Constants */ /* -------------------------------------------------------------------------- */ /// @dev The offset of the id we use to store the fraktion type @@ -37,7 +37,7 @@ library ContentIdLib { uint256 internal constant FRAKTION_TYPE_DIAMOND = 6; /* -------------------------------------------------------------------------- */ - /* Helper method's */ + /* Helper functions */ /* -------------------------------------------------------------------------- */ /// @dev Build a fraktion id from a content id diff --git a/contracts/minter/IMinter.sol b/contracts/minter/IMinter.sol index 62c8060..4a0920b 100644 --- a/contracts/minter/IMinter.sol +++ b/contracts/minter/IMinter.sol @@ -10,7 +10,7 @@ import { FraktionId } from "../libs/FraktionId.sol"; /// @custom:security-contact contact@frak.id interface IMinter { /* -------------------------------------------------------------------------- */ - /* Error's */ + /* Errors */ /* -------------------------------------------------------------------------- */ /// @dev Error emitted when the input supply is invalid @@ -23,7 +23,7 @@ interface IMinter { error TooManyFraktion(); /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when a new content is minted diff --git a/contracts/minter/Minter.sol b/contracts/minter/Minter.sol index 14179fe..21c4788 100644 --- a/contracts/minter/Minter.sol +++ b/contracts/minter/Minter.sol @@ -21,7 +21,7 @@ contract Minter is IMinter, FrakAccessControlUpgradeable, FraktionCostBadges, Mu using SafeTransferLib for address; /* -------------------------------------------------------------------------- */ - /* Error's */ + /* Errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256(bytes("InvalidAddress()")))' @@ -37,7 +37,7 @@ contract Minter is IMinter, FrakAccessControlUpgradeable, FraktionCostBadges, Mu uint256 private constant _TOO_MANY_FRAKTION_SELECTOR = 0xaa37c4ae; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev 'keccak256("ContentMinted(uint256,address)")' @@ -102,7 +102,7 @@ contract Minter is IMinter, FrakAccessControlUpgradeable, FraktionCostBadges, Mu } /* -------------------------------------------------------------------------- */ - /* External write function's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /** @@ -325,7 +325,7 @@ contract Minter is IMinter, FrakAccessControlUpgradeable, FraktionCostBadges, Mu } /* -------------------------------------------------------------------------- */ - /* Internal write function's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/minter/badges/FraktionCostBadges.sol b/contracts/minter/badges/FraktionCostBadges.sol index 8a80368..c88b0bb 100644 --- a/contracts/minter/badges/FraktionCostBadges.sol +++ b/contracts/minter/badges/FraktionCostBadges.sol @@ -11,14 +11,14 @@ import { InvalidFraktionType } from "../../utils/FrakErrors.sol"; /// @custom:security-contact contact@frak.id abstract contract FraktionCostBadges { /* -------------------------------------------------------------------------- */ - /* Error's */ + /* Errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256("InvalidFraktionType()"))' uint256 private constant _INVALID_FRAKTION_TYPE_SELECTOR = 0x3f126a45; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /** @@ -39,7 +39,7 @@ abstract contract FraktionCostBadges { mapping(FraktionId frakionId => uint96 cost) private fraktionBadges; /* -------------------------------------------------------------------------- */ - /* Abstract function's */ + /* Abstract functions */ /* -------------------------------------------------------------------------- */ /** @@ -51,7 +51,7 @@ abstract contract FraktionCostBadges { function updateCostBadge(FraktionId fraktionId, uint96 badge) external virtual; /* -------------------------------------------------------------------------- */ - /* Internal write function's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /** @@ -70,7 +70,7 @@ abstract contract FraktionCostBadges { } /* -------------------------------------------------------------------------- */ - /* Public read function's */ + /* Public read functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/reward/IRewarder.sol b/contracts/reward/IRewarder.sol index c27e8ec..d703067 100644 --- a/contracts/reward/IRewarder.sol +++ b/contracts/reward/IRewarder.sol @@ -12,7 +12,7 @@ interface IRewarder { error InvalidReward(); /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when a user is rewarded for his listen @@ -21,7 +21,7 @@ interface IRewarder { ); /* -------------------------------------------------------------------------- */ - /* External write function's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /// @dev Directly pay a `listener` for the given frk `amount` (used for offchain to onchain wallet migration) @@ -46,7 +46,7 @@ interface IRewarder { function updateTpu(uint256 newTpu) external; /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /// @dev Get the current TPU diff --git a/contracts/reward/Rewarder.sol b/contracts/reward/Rewarder.sol index 9fa18f7..3841097 100644 --- a/contracts/reward/Rewarder.sol +++ b/contracts/reward/Rewarder.sol @@ -33,7 +33,7 @@ contract Rewarder is using SafeTransferLib for address; /* -------------------------------------------------------------------------- */ - /* Constant's */ + /* Constants */ /* -------------------------------------------------------------------------- */ // The cap of frak token we can mint for the reward @@ -55,7 +55,7 @@ contract Rewarder is uint256 private constant FEE_PERCENT = 2; /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256(bytes("InvalidAddress()")))' @@ -71,7 +71,7 @@ contract Rewarder is uint256 private constant _REWARD_TOO_LARGE_SELECTOR = 0x71009bf7; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when a user is rewarded for his listen @@ -151,7 +151,7 @@ contract Rewarder is } /* -------------------------------------------------------------------------- */ - /* External write function's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /// @dev Directly pay a `listener` for the given frk `amount` (used for offchain to onchain wallet migration) @@ -338,7 +338,7 @@ contract Rewarder is } /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /// @dev Get the current TPU @@ -352,7 +352,7 @@ contract Rewarder is } /* -------------------------------------------------------------------------- */ - /* Internal write function's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /// @dev Compute the reward of the given content @@ -452,7 +452,7 @@ contract Rewarder is } /* -------------------------------------------------------------------------- */ - /* Internal view function's */ + /* Internal view functions */ /* -------------------------------------------------------------------------- */ /// @dev Compute the earning factor for the given listener @@ -512,7 +512,7 @@ contract Rewarder is } /* -------------------------------------------------------------------------- */ - /* Internal pure function's */ + /* Internal pure functions */ /* -------------------------------------------------------------------------- */ /// @dev Compute the base reward for the given `contentType` diff --git a/contracts/reward/contentPool/ContentPool.sol b/contracts/reward/contentPool/ContentPool.sol index 6b199a2..fd540c6 100644 --- a/contracts/reward/contentPool/ContentPool.sol +++ b/contracts/reward/contentPool/ContentPool.sol @@ -19,7 +19,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa using EnumerableSet for EnumerableSet.UintSet; /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256(bytes("NoReward()")))' @@ -32,7 +32,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa uint256 private constant _POOL_STATE_ALREADY_CLAIMED_SELECTOR = 0xa917cd37; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev 'keccak256(bytes("PoolRewardAdded(uint256,uint256)"))' @@ -48,7 +48,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa 0x1ecb16c5f7a5b459071d87585a22f39d1e567f4c0406de6e4b654a4c74b0908b; /* -------------------------------------------------------------------------- */ - /* Constant's */ + /* Constants */ /* -------------------------------------------------------------------------- */ /// @dev Maximum reward we can have in a pool @@ -88,7 +88,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa } /* -------------------------------------------------------------------------- */ - /* External write funtion's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /// @dev Add a new `rewardAmount` to the pool for the content `contentId` @@ -174,7 +174,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa } /* -------------------------------------------------------------------------- */ - /* Internal write function's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /// @dev Update the participants of a pool after fraktion transfer @@ -477,7 +477,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa } /* -------------------------------------------------------------------------- */ - /* Internal pure function's */ + /* Internal pure functions */ /* -------------------------------------------------------------------------- */ /** @@ -520,7 +520,7 @@ contract ContentPool is IContentPool, FrakAccessControlUpgradeable, PushPullRewa } /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/reward/contentPool/IContentPool.sol b/contracts/reward/contentPool/IContentPool.sol index f5ced9f..67c204f 100644 --- a/contracts/reward/contentPool/IContentPool.sol +++ b/contracts/reward/contentPool/IContentPool.sol @@ -10,7 +10,7 @@ import { ContentId } from "../../libs/ContentId.sol"; /// @custom:security-contact contact@frak.id interface IContentPool is FraktionTransferCallback { /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev The pool state is closed @@ -20,7 +20,7 @@ interface IContentPool is FraktionTransferCallback { error PoolStateAlreadyClaimed(); /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when a reward is added to the pool @@ -33,7 +33,7 @@ interface IContentPool is FraktionTransferCallback { event ParticipantShareUpdated(address indexed user, uint256 indexed contentId, uint256 shares); /* -------------------------------------------------------------------------- */ - /* Struct's */ + /* Structs */ /* -------------------------------------------------------------------------- */ /** @@ -85,7 +85,7 @@ interface IContentPool is FraktionTransferCallback { } /* -------------------------------------------------------------------------- */ - /* External write funtion's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /// @dev Add a new `rewardAmount` to the pool for the content `contentId` @@ -95,7 +95,7 @@ interface IContentPool is FraktionTransferCallback { function computeAllPoolsBalance(address user) external; /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/roles/FrakAccessControlUpgradeable.sol b/contracts/roles/FrakAccessControlUpgradeable.sol index 53d692f..6b0f9c1 100644 --- a/contracts/roles/FrakAccessControlUpgradeable.sol +++ b/contracts/roles/FrakAccessControlUpgradeable.sol @@ -21,14 +21,14 @@ import { NotAuthorized, RenounceForCallerOnly } from "../utils/FrakErrors.sol"; */ abstract contract FrakAccessControlUpgradeable is Initializable, ContextUpgradeable, UUPSUpgradeable { /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256(bytes("NotAuthorized()")))' uint256 private constant _NOT_AUTHORIZED_SELECTOR = 0xea8e4eb5; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when a role is granted @@ -67,7 +67,7 @@ abstract contract FrakAccessControlUpgradeable is Initializable, ContextUpgradea } /* -------------------------------------------------------------------------- */ - /* External write function's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ /// @dev Grant the `role` to the `account` @@ -88,7 +88,7 @@ abstract contract FrakAccessControlUpgradeable is Initializable, ContextUpgradea } /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /// @dev Check if the user has the given role @@ -97,7 +97,7 @@ abstract contract FrakAccessControlUpgradeable is Initializable, ContextUpgradea } /* -------------------------------------------------------------------------- */ - /* Internal write function's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /// @dev Grant the `role` to the `account` @@ -117,7 +117,7 @@ abstract contract FrakAccessControlUpgradeable is Initializable, ContextUpgradea } /* -------------------------------------------------------------------------- */ - /* Internal view function's */ + /* Internal view functions */ /* -------------------------------------------------------------------------- */ /// @dev Check that the calling user have the right `role` @@ -145,7 +145,7 @@ abstract contract FrakAccessControlUpgradeable is Initializable, ContextUpgradea } /* -------------------------------------------------------------------------- */ - /* Modifier's */ + /* Modifiers */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/tokens/FrakToken.sol b/contracts/tokens/FrakToken.sol index dec4b8a..7bc5bd5 100644 --- a/contracts/tokens/FrakToken.sol +++ b/contracts/tokens/FrakToken.sol @@ -16,14 +16,14 @@ import { ECDSA } from "solady/utils/ECDSA.sol"; /// @custom:security-contact contact@frak.id contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Diamond, IFrakToken { /* -------------------------------------------------------------------------- */ - /* Constant's */ + /* Constants */ /* -------------------------------------------------------------------------- */ /// @dev Maximum cap of token, at 3 billion FRK uint256 private constant _cap = 3_000_000_000 ether; /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev Gap variable for the previous domain separator variable from the EIP712 Base contract @@ -43,7 +43,7 @@ contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Diam } /* -------------------------------------------------------------------------- */ - /* External write function's */ + /* External write functions */ /* -------------------------------------------------------------------------- */ function initialize() external initializer { diff --git a/contracts/utils/EIP712Diamond.sol b/contracts/utils/EIP712Diamond.sol index 15f07d4..75a3bcc 100644 --- a/contracts/utils/EIP712Diamond.sol +++ b/contracts/utils/EIP712Diamond.sol @@ -17,7 +17,7 @@ contract EIP712Diamond { } /* -------------------------------------------------------------------------- */ - /* Constant's */ + /* Constants */ /* -------------------------------------------------------------------------- */ /// @dev The current version of the erc712, 2 since we switch between inline storage to diamond storage diff --git a/contracts/utils/IPushPullReward.sol b/contracts/utils/IPushPullReward.sol index 953d028..5694e29 100644 --- a/contracts/utils/IPushPullReward.sol +++ b/contracts/utils/IPushPullReward.sol @@ -7,7 +7,7 @@ pragma solidity 0.8.21; /// @custom:security-contact contact@frak.id interface IPushPullReward { /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev Event emitted when a reward is added @@ -17,7 +17,7 @@ interface IPushPullReward { event RewardWithdrawed(address indexed user, uint256 amount, uint256 fees); /* -------------------------------------------------------------------------- */ - /* External virtual function's */ + /* External virtual functions */ /* -------------------------------------------------------------------------- */ /** @@ -31,7 +31,7 @@ interface IPushPullReward { function withdrawFounds(address user) external; /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/utils/PushPullReward.sol b/contracts/utils/PushPullReward.sol index 1ee9312..4073e73 100644 --- a/contracts/utils/PushPullReward.sol +++ b/contracts/utils/PushPullReward.sol @@ -14,7 +14,7 @@ abstract contract PushPullReward is IPushPullReward, Initializable { using SafeTransferLib for address; /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256(bytes("InvalidAddress()")))' @@ -24,7 +24,7 @@ abstract contract PushPullReward is IPushPullReward, Initializable { uint256 private constant _REWARD_TOO_LARGE_SELECTOR = 0x71009bf7; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /// @dev 'keccak256(bytes("RewardAdded(address,uint256)"))' @@ -53,7 +53,7 @@ abstract contract PushPullReward is IPushPullReward, Initializable { } /* -------------------------------------------------------------------------- */ - /* External virtual function's */ + /* External virtual functions */ /* -------------------------------------------------------------------------- */ /** @@ -67,7 +67,7 @@ abstract contract PushPullReward is IPushPullReward, Initializable { function withdrawFounds(address user) external virtual; /* -------------------------------------------------------------------------- */ - /* External view function's */ + /* External view functions */ /* -------------------------------------------------------------------------- */ /** @@ -84,7 +84,7 @@ abstract contract PushPullReward is IPushPullReward, Initializable { } /* -------------------------------------------------------------------------- */ - /* Internal write function's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/wallets/FrakTreasuryWallet.sol b/contracts/wallets/FrakTreasuryWallet.sol index 8607dfc..737423d 100644 --- a/contracts/wallets/FrakTreasuryWallet.sol +++ b/contracts/wallets/FrakTreasuryWallet.sol @@ -19,7 +19,7 @@ contract FrakTreasuryWallet is FrakAccessControlUpgradeable, Multicallable { using SafeTransferLib for address; /* -------------------------------------------------------------------------- */ - /* Constant's */ + /* Constants */ /* -------------------------------------------------------------------------- */ // The cap of frk token for the treasury @@ -32,7 +32,7 @@ contract FrakTreasuryWallet is FrakAccessControlUpgradeable, Multicallable { uint256 internal constant FRK_MINTING_AMOUNT = 1_000_000 ether; /* -------------------------------------------------------------------------- */ - /* Custom error's */ + /* Custom errors */ /* -------------------------------------------------------------------------- */ /// @dev 'bytes4(keccak256(bytes("InvalidAddress()")))' @@ -48,7 +48,7 @@ contract FrakTreasuryWallet is FrakAccessControlUpgradeable, Multicallable { uint256 private constant _REWARD_TOO_LARGE_SELECTOR = 0x71009bf7; /* -------------------------------------------------------------------------- */ - /* Event's */ + /* Events */ /* -------------------------------------------------------------------------- */ /** diff --git a/contracts/wallets/MultiVestingWallets.sol b/contracts/wallets/MultiVestingWallets.sol index 24676c9..93af0d3 100644 --- a/contracts/wallets/MultiVestingWallets.sol +++ b/contracts/wallets/MultiVestingWallets.sol @@ -113,7 +113,7 @@ contract MultiVestingWallets is FrakAccessControlUpgradeable { /** * @notice Fake an ERC20-like contract allowing it to be displayed from wallets. - * @return the frk's decimals value. + * @return the frk decimals value. */ function decimals() external pure returns (uint8) { return 18; diff --git a/script/utils/UpgradeScript.s.sol b/script/utils/UpgradeScript.s.sol index 8c33e26..6555a11 100644 --- a/script/utils/UpgradeScript.s.sol +++ b/script/utils/UpgradeScript.s.sol @@ -69,7 +69,7 @@ abstract contract UpgradeScript is Script { } /* -------------------------------------------------------------------------- */ - /* Internal write method's */ + /* Internal write functions */ /* -------------------------------------------------------------------------- */ /** @@ -134,7 +134,7 @@ abstract contract UpgradeScript is Script { } /* -------------------------------------------------------------------------- */ - /* Internal read method's */ + /* Internal read functions */ /* -------------------------------------------------------------------------- */ /** diff --git a/test/fraktions/FraktionTokens.t.sol b/test/fraktions/FraktionTokens.t.sol index 162ca64..903a4fc 100644 --- a/test/fraktions/FraktionTokens.t.sol +++ b/test/fraktions/FraktionTokens.t.sol @@ -15,7 +15,7 @@ contract FraktionTokensTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { @@ -79,7 +79,7 @@ contract FraktionTokensTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Supply related test's */ + /* Supply related tests */ /* -------------------------------------------------------------------------- */ function test_supply_ok() public withEmptySupply(contentId.commonFraktionId()) asDeployer { @@ -137,7 +137,7 @@ contract FraktionTokensTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Transfer callback's */ + /* Transfer callbacks */ /* -------------------------------------------------------------------------- */ function test_setUpTransferCallback_ok() public { @@ -301,7 +301,7 @@ contract FraktionTokensTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Some helper's */ + /* Some helpers */ /* -------------------------------------------------------------------------- */ function _getMintContentParams() internal pure returns (uint256[] memory suppliesToType) { diff --git a/test/minter/Minter.t.sol b/test/minter/Minter.t.sol index dffff8d..8287bd2 100644 --- a/test/minter/Minter.t.sol +++ b/test/minter/Minter.t.sol @@ -17,7 +17,7 @@ contract MinterTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { @@ -35,7 +35,7 @@ contract MinterTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Add content test's */ + /* Add content tests */ /* -------------------------------------------------------------------------- */ function test_addContent_ok() public { @@ -72,7 +72,7 @@ contract MinterTest is FrakTest { minter.addContent(contentOwner, 20, 7, 3, 21); } - /// @dev Different mint method's benchmark + /// @dev Different mint functions benchmark function test_benchmarkAddContent_ok() public asDeployer { // Warm up storage minter.addAutoMintedContent(contentOwner); @@ -217,7 +217,7 @@ contract MinterTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Supply method's */ + /* Supply functions */ /* -------------------------------------------------------------------------- */ function test_increaseSupply_ok() public withEmptySupply(contentId.commonFraktionId()) { diff --git a/test/reward/RewarderConfig.t.sol b/test/reward/RewarderConfig.t.sol index 8d03c78..467c8fe 100644 --- a/test/reward/RewarderConfig.t.sol +++ b/test/reward/RewarderConfig.t.sol @@ -21,7 +21,7 @@ contract RewarderConfigTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { diff --git a/test/reward/pools/ContentPool.t.sol b/test/reward/pools/ContentPool.t.sol index a426ed5..2e0049b 100644 --- a/test/reward/pools/ContentPool.t.sol +++ b/test/reward/pools/ContentPool.t.sol @@ -28,7 +28,7 @@ contract ContentPoolTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { @@ -291,7 +291,7 @@ contract ContentPoolTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Test helper's */ + /* Test helpers */ /* -------------------------------------------------------------------------- */ function _mintCommonForUser() private { diff --git a/test/reward/pools/ReferralPool.t.sol b/test/reward/pools/ReferralPool.t.sol index 12d988c..f4c6f48 100644 --- a/test/reward/pools/ReferralPool.t.sol +++ b/test/reward/pools/ReferralPool.t.sol @@ -12,7 +12,7 @@ contract ReferralPoolTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { diff --git a/test/tokens/FrakToken.t.sol b/test/tokens/FrakToken.t.sol index 265e132..1e7e4a4 100644 --- a/test/tokens/FrakToken.t.sol +++ b/test/tokens/FrakToken.t.sol @@ -13,7 +13,7 @@ contract FrakTokenTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { @@ -83,7 +83,7 @@ contract FrakTokenTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Permit test's */ + /* Permit tests */ /* -------------------------------------------------------------------------- */ function test_permit_ok() public { diff --git a/test/wallets/FrakTeasuryWallet.t.sol b/test/wallets/FrakTeasuryWallet.t.sol index 71730c9..2cad62a 100644 --- a/test/wallets/FrakTeasuryWallet.t.sol +++ b/test/wallets/FrakTeasuryWallet.t.sol @@ -12,7 +12,7 @@ contract FrakTeasuryWalletTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { @@ -130,7 +130,7 @@ contract FrakTeasuryWalletTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Helper's */ + /* Helpers */ /* -------------------------------------------------------------------------- */ function _baseBatchTransferParam(uint256 amount) private view returns (address[] memory, uint256[] memory) { return _baseBatchTransferParam(user, amount); diff --git a/test/wallets/MultiVestingWallets.t.sol b/test/wallets/MultiVestingWallets.t.sol index 3531e5e..d3354b7 100644 --- a/test/wallets/MultiVestingWallets.t.sol +++ b/test/wallets/MultiVestingWallets.t.sol @@ -17,7 +17,7 @@ contract MultiVestingWalletsTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { @@ -279,7 +279,7 @@ contract MultiVestingWalletsTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Test helper's */ + /* Test helpers */ /* -------------------------------------------------------------------------- */ modifier withUserVesting() { diff --git a/test/wallets/VestingWalletFactory.t.sol b/test/wallets/VestingWalletFactory.t.sol index b5813c0..e3ed207 100644 --- a/test/wallets/VestingWalletFactory.t.sol +++ b/test/wallets/VestingWalletFactory.t.sol @@ -12,7 +12,7 @@ contract VestingWalletFactoryTest is FrakTest { } /* -------------------------------------------------------------------------- */ - /* Init test's */ + /* Init tests */ /* -------------------------------------------------------------------------- */ function test_canBeDeployedAndInit_ok() public { From 071cafb14b4665c4da399f7429c13722bee74395 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Fri, 20 Oct 2023 11:45:21 +0200 Subject: [PATCH 12/16] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Adding=20update=20me?= =?UTF-8?q?thods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 90 +++++++++++++------------- contracts/fraktions/FraktionTokens.sol | 9 +++ contracts/tokens/FrakToken.sol | 11 +++- contracts/utils/EIP712Diamond.sol | 4 -- test/FrakTest.sol | 7 ++ test/fraktions/FraktionTokens.t.sol | 4 ++ test/tokens/FrakToken.t.sol | 4 ++ 7 files changed, 79 insertions(+), 50 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 62e9ab8..e0682fa 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -5,34 +5,34 @@ ContentPoolTest:test_canBeDeployedAndInit_ok() (gas: 2820972) ContentPoolTest:test_getRewardStates_ok() (gas: 223662) ContentPoolTest:test_initialize_InitTwice_ko() (gas: 17982) ContentPoolTest:test_participantStates_ok() (gas: 220752) -ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428734) -ContentPoolTest:test_updateUserAndPool_ok() (gas: 325496) -ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539524) -ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713328) -ContentPoolTest:test_updateUser_ok() (gas: 400285) +ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428822) +ContentPoolTest:test_updateUserAndPool_ok() (gas: 325566) +ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539590) +ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713487) +ContentPoolTest:test_updateUser_ok() (gas: 400356) FrakTeasuryWalletTest:test_canBeDeployedAndInit_ok() (gas: 1773426) FrakTeasuryWalletTest:test_initialize_InitTwice_ko() (gas: 17937) FrakTeasuryWalletTest:test_transferBatch_InvalidArray_ko() (gas: 28753) -FrakTeasuryWalletTest:test_transferBatch_NoReward_ko() (gas: 34394) -FrakTeasuryWalletTest:test_transferBatch_NotEnoughTreasury_ko() (gas: 11334820) +FrakTeasuryWalletTest:test_transferBatch_NoReward_ko() (gas: 34416) +FrakTeasuryWalletTest:test_transferBatch_NotEnoughTreasury_ko() (gas: 11346454) FrakTeasuryWalletTest:test_transferBatch_NotMinter_ko() (gas: 18928) -FrakTeasuryWalletTest:test_transferBatch_RewardTooLarge_ko() (gas: 34409) -FrakTeasuryWalletTest:test_transferBatch_ok() (gas: 137867) +FrakTeasuryWalletTest:test_transferBatch_RewardTooLarge_ko() (gas: 34431) +FrakTeasuryWalletTest:test_transferBatch_ok() (gas: 137933) FrakTeasuryWalletTest:test_transfer_InvalidAddress_ko() (gas: 18375) FrakTeasuryWalletTest:test_transfer_NoReward_ko() (gas: 20508) -FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11333531) +FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11345164) FrakTeasuryWalletTest:test_transfer_NotMinter_ko() (gas: 17684) FrakTeasuryWalletTest:test_transfer_RewardTooLarge_ko() (gas: 20534) -FrakTeasuryWalletTest:test_transfer_ok() (gas: 136105) -FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3375) -FrakTokenTest:test_burn_ok() (gas: 53304) -FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 2537901) +FrakTeasuryWalletTest:test_transfer_ok() (gas: 136171) +FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3408) +FrakTokenTest:test_burn_ok() (gas: 53321) +FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 4966501) FrakTokenTest:test_cap_ok() (gas: 10366) FrakTokenTest:test_decimals_ok() (gas: 10426) -FrakTokenTest:test_initialize_InitTwice_ko() (gas: 15737) +FrakTokenTest:test_initialize_InitTwice_ko() (gas: 15759) FrakTokenTest:test_mint_CapExceed_ko() (gas: 88431) FrakTokenTest:test_mint_InvalidRole_ko() (gas: 17704) -FrakTokenTest:test_mint_ok() (gas: 68197) +FrakTokenTest:test_mint_ok() (gas: 68219) FrakTokenTest:test_name_ok() (gas: 14776) FrakTokenTest:test_permit_DelayExpired_ko() (gas: 28069) FrakTokenTest:test_permit_InvalidNonce_ko() (gas: 50313) @@ -46,12 +46,12 @@ FraktionCostBadgesTest:test_updatePrice_InvalidRole_ko() (gas: 17661) FraktionCostBadgesTest:test_updatePrice_ok() (gas: 126566) FraktionTokensTest:test_addContent_InvalidRole_ko() (gas: 18848) FraktionTokensTest:test_addContent_SupplyUpdateNotAllowed_ko() (gas: 75153) -FraktionTokensTest:test_addContent_ok() (gas: 330042) +FraktionTokensTest:test_addContent_ok() (gas: 330020) FraktionTokensTest:test_batchBalance_ok() (gas: 59879) FraktionTokensTest:test_burn_ok() (gas: 49561) -FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 3732947) +FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 7357020) FraktionTokensTest:test_initialize_InitTwice_ko() (gas: 16030) -FraktionTokensTest:test_ownerOf_ok() (gas: 16910) +FraktionTokensTest:test_ownerOf_ok() (gas: 16888) FraktionTokensTest:test_permitTransferAll_DelayExpired_ko() (gas: 27984) FraktionTokensTest:test_permitTransferAll_InvalidNonce_ko() (gas: 50430) FraktionTokensTest:test_permitTransferAll_InvalidSigner_ko() (gas: 53829) @@ -77,31 +77,31 @@ MinterTest:test_mintFreeFraktion_ExpectingOnlyFreeFraktion_ko() (gas: 40161) MinterTest:test_mintFreeFraktion_TooManyFraktion_ko() (gas: 66109) MinterTest:test_mintFreeFraktion_ok() (gas: 62919) MultiVestingWalletsTest:test_canBeDeployedAndInit_ok() (gas: 2732546) -MultiVestingWalletsTest:test_createVestBatch() (gas: 210743) +MultiVestingWalletsTest:test_createVestBatch() (gas: 210765) MultiVestingWalletsTest:test_createVestBatch_ArrayInvalidLength_ko() (gas: 79092) MultiVestingWalletsTest:test_createVestBatch_EmptyArray_ko() (gas: 78892) -MultiVestingWalletsTest:test_createVestBatch_NotEnoughReserve_ko() (gas: 85489) +MultiVestingWalletsTest:test_createVestBatch_NotEnoughReserve_ko() (gas: 85511) MultiVestingWalletsTest:test_createVestBatch_NotManager_ko() (gas: 80929) -MultiVestingWalletsTest:test_createVest_InvalidAddress_ko() (gas: 81951) +MultiVestingWalletsTest:test_createVest_InvalidAddress_ko() (gas: 81973) MultiVestingWalletsTest:test_createVest_InvalidDuration_ko() (gas: 80515) -MultiVestingWalletsTest:test_createVest_InvalidReward_ko() (gas: 81975) +MultiVestingWalletsTest:test_createVest_InvalidReward_ko() (gas: 81997) MultiVestingWalletsTest:test_createVest_InvalidStartDateTooFar_ko() (gas: 80524) MultiVestingWalletsTest:test_createVest_InvalidStartDate_ko() (gas: 80564) -MultiVestingWalletsTest:test_createVest_NotEnoughReserve_ko() (gas: 84054) +MultiVestingWalletsTest:test_createVest_NotEnoughReserve_ko() (gas: 84076) MultiVestingWalletsTest:test_createVest_NotManager_ko() (gas: 79675) -MultiVestingWalletsTest:test_createVest_TooLargeReward_ko() (gas: 82044) -MultiVestingWalletsTest:test_createVest_ok() (gas: 209063) +MultiVestingWalletsTest:test_createVest_TooLargeReward_ko() (gas: 82066) +MultiVestingWalletsTest:test_createVest_ok() (gas: 209085) MultiVestingWalletsTest:test_decimals_ok() (gas: 10391) MultiVestingWalletsTest:test_initialize_InitTwice_ko() (gas: 18027) MultiVestingWalletsTest:test_name_ok() (gas: 12085) -MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233627) -MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228564) -MultiVestingWalletsTest:test_release_ok() (gas: 238030) +MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233671) +MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228608) +MultiVestingWalletsTest:test_release_ok() (gas: 238074) MultiVestingWalletsTest:test_symbol_ok() (gas: 12117) -MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103634) -MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208275) -MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209478) -MultiVestingWalletsTest:test_transfer_ok() (gas: 226470) +MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103766) +MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208297) +MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209500) +MultiVestingWalletsTest:test_transfer_ok() (gas: 226492) ReferralPoolTest:test_canBeDeployedAndInit_ok() (gas: 1690025) ReferralPoolTest:test_initialize_InitTwice_ko() (gas: 17881) RewarderConfigTest:test_canBeDeployedAndInit_ok() (gas: 2597849) @@ -114,34 +114,34 @@ RewarderConfigTest:test_updateListenerBadge_InvalidRole_ko() (gas: 17711) RewarderConfigTest:test_updateListenerBadge_ok() (gas: 46543) RewarderConfigTest:test_updateTpu_InvalidRole_ko() (gas: 15412) RewarderConfigTest:test_updateTpu_ok() (gas: 23775) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139443) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139421) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_EmptyAmount_ko() (gas: 81351) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidArray_ko() (gas: 79575) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidRole_ko() (gas: 80462) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeAmount_ko() (gas: 81409) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeArray_ko() (gas: 82898) -RewarderDirectPaymentTest:test_payUserDirectly() (gas: 111283) +RewarderDirectPaymentTest:test_payUserDirectly() (gas: 111305) RewarderDirectPaymentTest:test_payUserDirectly_InvalidAddress_ko() (gas: 77950) RewarderDirectPaymentTest:test_payUserDirectly_InvalidReward_ko() (gas: 88598) RewarderDirectPaymentTest:test_payUserDirectly_InvalidRole_ko() (gas: 79280) RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105810) -RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212716) -RewarderTest:test_pay_FreeFraktion_ok() (gas: 191971) +RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212628) +RewarderTest:test_pay_FreeFraktion_ok() (gas: 191993) RewarderTest:test_pay_InvalidAddress_ko() (gas: 21620) RewarderTest:test_pay_InvalidArray_ko() (gas: 38041) -RewarderTest:test_pay_InvalidContent_ko() (gas: 56871) +RewarderTest:test_pay_InvalidContent_ko() (gas: 56849) RewarderTest:test_pay_InvalidRoles_ko() (gas: 21259) RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367580) RewarderTest:test_pay_PayedFraktions_TooMuchListenCounts_ko() (gas: 167427) -RewarderTest:test_pay_PayedFraktions_ok() (gas: 405472) +RewarderTest:test_pay_PayedFraktions_ok() (gas: 405494) RewarderTest:test_pay_TooLargeReward_ko() (gas: 231010) VestingWalletFactoryTest:test_canBeDeployedAndInit_ok() (gas: 2093328) VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) -WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359166) -WalletMigratorTest:test_claimAllFounds_ok() (gas: 359314) -WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634791) -WalletMigratorTest:test_fullMigration_ok() (gas: 634092) +WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359100) +WalletMigratorTest:test_claimAllFounds_ok() (gas: 359248) +WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634747) +WalletMigratorTest:test_fullMigration_ok() (gas: 634048) WalletMigratorTest:test_migrateFrationsForUser_ok() (gas: 269269) WalletMigratorTest:test_migrateFrations_ok() (gas: 269384) -WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144617) -WalletMigratorTest:test_migrateFrk_ok() (gas: 144814) \ No newline at end of file +WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144683) +WalletMigratorTest:test_migrateFrk_ok() (gas: 144880) \ No newline at end of file diff --git a/contracts/fraktions/FraktionTokens.sol b/contracts/fraktions/FraktionTokens.sol index 6e7da4b..aa37a16 100644 --- a/contracts/fraktions/FraktionTokens.sol +++ b/contracts/fraktions/FraktionTokens.sol @@ -84,6 +84,10 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP _disableInitializers(); } + /* -------------------------------------------------------------------------- */ + /* Versioning */ + /* -------------------------------------------------------------------------- */ + function initialize(string calldata metadatalUrl) external initializer { __ERC1155_init(metadatalUrl); __FrakAccessControlUpgradeable_Minter_init(); @@ -92,6 +96,11 @@ contract FraktionTokens is FrakAccessControlUpgradeable, ERC1155Upgradeable, EIP _currentContentId = 1; } + /// @dev Update to diamond Eip712 + function updateToDiamondEip712() external reinitializer(3) { + _initializeEIP712("Fraktions"); + } + /* -------------------------------------------------------------------------- */ /* External write functions */ /* -------------------------------------------------------------------------- */ diff --git a/contracts/tokens/FrakToken.sol b/contracts/tokens/FrakToken.sol index 7bc5bd5..23a0d6d 100644 --- a/contracts/tokens/FrakToken.sol +++ b/contracts/tokens/FrakToken.sol @@ -43,7 +43,7 @@ contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Diam } /* -------------------------------------------------------------------------- */ - /* External write functions */ + /* Versioning */ /* -------------------------------------------------------------------------- */ function initialize() external initializer { @@ -55,6 +55,15 @@ contract FrakToken is ERC20Upgradeable, FrakAccessControlUpgradeable, EIP712Diam // Current version is 2, since we use a version to reset the domain separator post EIP712 updates } + /// @dev Update to diamond Eip712 + function updateToDiamondEip712() external reinitializer(3) { + _initializeEIP712("FRK"); + } + + /* -------------------------------------------------------------------------- */ + /* External write functions */ + /* -------------------------------------------------------------------------- */ + /// @dev Mint some FRK function mint(address to, uint256 amount) external override onlyRole(FrakRoles.MINTER) { if (totalSupply() + amount > _cap) revert CapExceed(); diff --git a/contracts/utils/EIP712Diamond.sol b/contracts/utils/EIP712Diamond.sol index 75a3bcc..b93363c 100644 --- a/contracts/utils/EIP712Diamond.sol +++ b/contracts/utils/EIP712Diamond.sol @@ -48,10 +48,6 @@ contract EIP712Diamond { /// @dev init function function _initializeEIP712(string memory name) internal { - // Ensure the domain separator is currently empty - bytes32 domainSeparator = _getEIP712Storage()._domainSeperator; - if (domainSeparator != 0x0) revert(); - // Build and set the domain separator _getEIP712Storage()._domainSeperator = keccak256( abi.encode( diff --git a/test/FrakTest.sol b/test/FrakTest.sol index 5cbf049..9a8d4de 100644 --- a/test/FrakTest.sol +++ b/test/FrakTest.sol @@ -15,6 +15,7 @@ import { Rewarder } from "@frak/reward/Rewarder.sol"; import { FrakRoles } from "@frak/roles/FrakRoles.sol"; import { PRBTest } from "@prb/test/PRBTest.sol"; import { ERC1967Proxy } from "openzeppelin/proxy/ERC1967/ERC1967Proxy.sol"; +import { UUPSUpgradeable } from "openzeppelin/proxy/utils/UUPSUpgradeable.sol"; /// Testing the frak l2 token contract FrakTest is PRBTest { @@ -299,6 +300,12 @@ contract FrakTest is PRBTest { vm.label(createdAddress, label); } + /// @dev Deploy the given proxy + function _updateProxy(address _proxy, address _logic, bytes memory _update) internal { + UUPSUpgradeable proxy = UUPSUpgradeable(_proxy); + proxy.upgradeToAndCall(_logic, _update); + } + /* -------------------------------------------------------------------------- */ /* Signature helpers */ /* -------------------------------------------------------------------------- */ diff --git a/test/fraktions/FraktionTokens.t.sol b/test/fraktions/FraktionTokens.t.sol index 903a4fc..15ed969 100644 --- a/test/fraktions/FraktionTokens.t.sol +++ b/test/fraktions/FraktionTokens.t.sol @@ -23,6 +23,10 @@ contract FraktionTokensTest is FrakTest { bytes memory initData = abi.encodeCall(FraktionTokens.initialize, ("https://metadata/url")); address proxyAddress = _deployProxy(address(new FraktionTokens()), initData, "FraktionTokensDeploy"); fraktionTokens = FraktionTokens(proxyAddress); + + // Can be updated + bytes memory updateData = bytes.concat(FraktionTokens.updateToDiamondEip712.selector); + _updateProxy(proxyAddress, address(new FraktionTokens()), updateData); } /// @dev Can't re-init diff --git a/test/tokens/FrakToken.t.sol b/test/tokens/FrakToken.t.sol index 1e7e4a4..d504e11 100644 --- a/test/tokens/FrakToken.t.sol +++ b/test/tokens/FrakToken.t.sol @@ -21,6 +21,10 @@ contract FrakTokenTest is FrakTest { bytes memory initData = abi.encodeWithSelector(FrakToken.initialize.selector); address proxyAddress = _deployProxy(address(new FrakToken()), initData, "FrakTokenDeploy"); frakToken = FrakToken(proxyAddress); + + // Can be updated + bytes memory updateData = bytes.concat(FrakToken.updateToDiamondEip712.selector); + _updateProxy(proxyAddress, address(new FrakToken()), updateData); } /// @dev Can't re-init From 1e35b7751564c2dcb7526ff272f88a5bf9ac54bd Mon Sep 17 00:00:00 2001 From: KONFeature Date: Fri, 20 Oct 2023 12:20:05 +0200 Subject: [PATCH 13/16] =?UTF-8?q?=F0=9F=90=9B=20Correct=20UUPS=20upgrade?= =?UTF-8?q?=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 6 +++--- test/FrakTest.sol | 7 ------- test/fraktions/FraktionTokens.t.sol | 2 +- test/tokens/FrakToken.t.sol | 2 +- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index e0682fa..1be6e61 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -24,9 +24,9 @@ FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11345164) FrakTeasuryWalletTest:test_transfer_NotMinter_ko() (gas: 17684) FrakTeasuryWalletTest:test_transfer_RewardTooLarge_ko() (gas: 20534) FrakTeasuryWalletTest:test_transfer_ok() (gas: 136171) -FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3408) +FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3433) FrakTokenTest:test_burn_ok() (gas: 53321) -FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 4966501) +FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 4966458) FrakTokenTest:test_cap_ok() (gas: 10366) FrakTokenTest:test_decimals_ok() (gas: 10426) FrakTokenTest:test_initialize_InitTwice_ko() (gas: 15759) @@ -49,7 +49,7 @@ FraktionTokensTest:test_addContent_SupplyUpdateNotAllowed_ko() (gas: 75153) FraktionTokensTest:test_addContent_ok() (gas: 330020) FraktionTokensTest:test_batchBalance_ok() (gas: 59879) FraktionTokensTest:test_burn_ok() (gas: 49561) -FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 7357020) +FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 7356977) FraktionTokensTest:test_initialize_InitTwice_ko() (gas: 16030) FraktionTokensTest:test_ownerOf_ok() (gas: 16888) FraktionTokensTest:test_permitTransferAll_DelayExpired_ko() (gas: 27984) diff --git a/test/FrakTest.sol b/test/FrakTest.sol index 9a8d4de..5cbf049 100644 --- a/test/FrakTest.sol +++ b/test/FrakTest.sol @@ -15,7 +15,6 @@ import { Rewarder } from "@frak/reward/Rewarder.sol"; import { FrakRoles } from "@frak/roles/FrakRoles.sol"; import { PRBTest } from "@prb/test/PRBTest.sol"; import { ERC1967Proxy } from "openzeppelin/proxy/ERC1967/ERC1967Proxy.sol"; -import { UUPSUpgradeable } from "openzeppelin/proxy/utils/UUPSUpgradeable.sol"; /// Testing the frak l2 token contract FrakTest is PRBTest { @@ -300,12 +299,6 @@ contract FrakTest is PRBTest { vm.label(createdAddress, label); } - /// @dev Deploy the given proxy - function _updateProxy(address _proxy, address _logic, bytes memory _update) internal { - UUPSUpgradeable proxy = UUPSUpgradeable(_proxy); - proxy.upgradeToAndCall(_logic, _update); - } - /* -------------------------------------------------------------------------- */ /* Signature helpers */ /* -------------------------------------------------------------------------- */ diff --git a/test/fraktions/FraktionTokens.t.sol b/test/fraktions/FraktionTokens.t.sol index 15ed969..e266cfa 100644 --- a/test/fraktions/FraktionTokens.t.sol +++ b/test/fraktions/FraktionTokens.t.sol @@ -26,7 +26,7 @@ contract FraktionTokensTest is FrakTest { // Can be updated bytes memory updateData = bytes.concat(FraktionTokens.updateToDiamondEip712.selector); - _updateProxy(proxyAddress, address(new FraktionTokens()), updateData); + fraktionTokens.upgradeToAndCall(address(new FraktionTokens()), updateData); } /// @dev Can't re-init diff --git a/test/tokens/FrakToken.t.sol b/test/tokens/FrakToken.t.sol index d504e11..030a4bd 100644 --- a/test/tokens/FrakToken.t.sol +++ b/test/tokens/FrakToken.t.sol @@ -24,7 +24,7 @@ contract FrakTokenTest is FrakTest { // Can be updated bytes memory updateData = bytes.concat(FrakToken.updateToDiamondEip712.selector); - _updateProxy(proxyAddress, address(new FrakToken()), updateData); + frakToken.upgradeToAndCall(address(new FrakToken()), updateData); } /// @dev Can't re-init From 0b2432da4395413768456ff8403e6a6f14242988 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Mon, 23 Oct 2023 11:16:52 +0200 Subject: [PATCH 14/16] =?UTF-8?q?=F0=9F=94=A8=20Add=20a=20script=20to=20pe?= =?UTF-8?q?rform=20the=20version=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/UpdateToEip712Diamond.s.sol | 78 ++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 script/UpdateToEip712Diamond.s.sol diff --git a/script/UpdateToEip712Diamond.s.sol b/script/UpdateToEip712Diamond.s.sol new file mode 100644 index 0000000..b198f52 --- /dev/null +++ b/script/UpdateToEip712Diamond.s.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GNU GPLv3 +pragma solidity 0.8.21; + +import "forge-std/console.sol"; +import "forge-std/Script.sol"; +import { UpgradeScript } from "./utils/UpgradeScript.s.sol"; +import { FrakToken } from "@frak/tokens/FrakToken.sol"; +import { FraktionTokens } from "@frak/fraktions/FraktionTokens.sol"; +import { MultiVestingWallets } from "@frak/wallets/MultiVestingWallets.sol"; +import { VestingWalletFactory } from "@frak/wallets/VestingWalletFactory.sol"; +import { FrakTreasuryWallet } from "@frak/wallets/FrakTreasuryWallet.sol"; +import { ReferralPool } from "@frak/reward/referralPool/ReferralPool.sol"; +import { Minter } from "@frak/minter/Minter.sol"; +import { ContentPool } from "@frak/reward/contentPool/ContentPool.sol"; +import { Rewarder } from "@frak/reward/Rewarder.sol"; +import { FrakRoles } from "@frak/roles/FrakRoles.sol"; +import { WalletMigrator } from "@frak/wallets/WalletMigrator.sol"; + +contract UpdateToEip712Diamond is UpgradeScript { + function run() external { + // Get the current treasury wallet address + UpgradeScript.ContractProxyAddresses memory addresses = _currentProxyAddresses(); + + // Update all the tokens contracts + _updateToDiamondEip712(addresses); + + // Update the reward pools contracts + _updateRewardPoolsContracts(addresses); + + // Deploy the migrator contract + WalletMigrator walletMigrator = _deployMigrator(addresses); + console.log("Migrator deployed to %s", address(walletMigrator)); + } + + /// @dev Update every contracts + function _updateToDiamondEip712(UpgradeScript.ContractProxyAddresses memory addresses) internal deployerBroadcast { + // Deploy every contract + FrakToken frakToken = new FrakToken(); + FraktionTokens fraktionTokens = new FraktionTokens(); + + // Update frk proxy + bytes memory updateData = bytes.concat(FrakToken.updateToDiamondEip712.selector); + _upgradeToAndCall(addresses.frakToken, address(frakToken), updateData); + + // Update fraktion proxy + updateData = bytes.concat(FraktionTokens.updateToDiamondEip712.selector); + _upgradeToAndCall(addresses.fraktionTokens, address(fraktionTokens), updateData); + } + + function _updateRewardPoolsContracts(UpgradeScript.ContractProxyAddresses memory addresses) + internal + deployerBroadcast + { + ReferralPool referralPool = new ReferralPool(); + ContentPool contentPool = new ContentPool(); + Rewarder rewarder = new Rewarder(); + + _upgradeTo(addresses.contentPool, address(contentPool)); + _upgradeTo(addresses.rewarder, address(rewarder)); + _upgradeTo(addresses.referralPool, address(referralPool)); + } + + /// @dev Deploy the migrator contract + function _deployMigrator(UpgradeScript.ContractProxyAddresses memory addresses) + internal + deployerBroadcast + returns (WalletMigrator) + { + // Build the wallet migrator we will test + return new WalletMigrator( + addresses.frakToken, + addresses.fraktionTokens, + addresses.rewarder, + addresses.contentPool, + addresses.referralPool + ); + } +} From 638195d4987dba93cdc4d3671bdeb40a041842a4 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Mon, 23 Oct 2023 11:24:10 +0200 Subject: [PATCH 15/16] =?UTF-8?q?=F0=9F=9A=80=20Deploy=20update=20&=20wall?= =?UTF-8?q?et=20migrator=20to=20polygon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script/utils/DeployAllScript.s.sol | 3 ++- script/utils/UpgradeScript.s.sol | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/script/utils/DeployAllScript.s.sol b/script/utils/DeployAllScript.s.sol index 90d4200..e96865a 100644 --- a/script/utils/DeployAllScript.s.sol +++ b/script/utils/DeployAllScript.s.sol @@ -49,7 +49,8 @@ contract DeployAllScript is UpgradeScript { rewarder: rewarder, minter: minter, frakTreasuryWallet: treasuryWallet, - swapPool: address(1) + swapPool: address(1), + walletMigrator: address(1) }); _setProxyAddresses(addresses); } diff --git a/script/utils/UpgradeScript.s.sol b/script/utils/UpgradeScript.s.sol index 6555a11..a036b02 100644 --- a/script/utils/UpgradeScript.s.sol +++ b/script/utils/UpgradeScript.s.sol @@ -26,6 +26,7 @@ abstract contract UpgradeScript is Script { address minter; address frakTreasuryWallet; address swapPool; + address walletMigrator; } /// @dev Mapping of chainId -> proxy addresses @@ -47,12 +48,9 @@ abstract contract UpgradeScript is Script { rewarder: 0x8D9fa601DA1416b087E9db6B6EaD63D4920A4528, minter: 0x1adc8CAaA35551730eCd82e0eEA683Aa90dB6cf0, frakTreasuryWallet: 0x7053f61CEA3B7C3b5f0e14de6eEdB01cA1850408, - swapPool: 0xC01677Ec5eF3607364125Ab84F6FBb7d95B3D545 + swapPool: 0xC01677Ec5eF3607364125Ab84F6FBb7d95B3D545, + walletMigrator: 0xC9f4a01219240aEDfe9502fff0bdEEa5ea83E795 }); - // forge verify-contract --chain polygon 0x8a67c75F8C0bF37a06d92938e9C9e841506D37B0 MonoPool --constructor-args - // $(cast abi-encode "constructor(address,address,uint256,address,uint256)" - // 0x6261E4a478C98419EaFa6289509C49058D21Df8c 0x0000000000000000000000000000000000000000 100 - // 0x517ecFa01E2F9A6955d8DD04867613E41309213d 100) // Mumbai proxy address contractAddresses[80_001] = ContractProxyAddresses({ frakToken: 0xbCeE0E1C02E91EAFaEd69eD2B1DC5199789575df, @@ -64,7 +62,8 @@ abstract contract UpgradeScript is Script { rewarder: 0x0bD2a225E2c6173b42b907Cc4424076327D90F6F, minter: 0x8964e2Ed5fF27358c62a761f23957bd2b5165779, frakTreasuryWallet: 0x7CC62E1ecd246153DF4997352ec9C5fF172EE08C, - swapPool: 0xa5C6ff96B2417d5477d0ab27881b3D60675E0d30 + swapPool: 0xa5C6ff96B2417d5477d0ab27881b3D60675E0d30, + walletMigrator: 0xC2F4685B8d9fafc3172abA9a7FFd4B0Dd2bd2D5e }); } From 1ebe10f033933fdba0889511c8a69a5b285910d1 Mon Sep 17 00:00:00 2001 From: KONFeature Date: Mon, 23 Oct 2023 18:10:57 +0200 Subject: [PATCH 16/16] =?UTF-8?q?=F0=9F=90=9B=20useNonce=20method=20only?= =?UTF-8?q?=20as=20internal=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gas-snapshot | 102 +++---- contracts/utils/EIP712Diamond.sol | 10 +- package.json | 4 +- pnpm-lock.yaml | 438 +++++++++++++++--------------- 4 files changed, 281 insertions(+), 273 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 1be6e61..913519b 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -5,28 +5,28 @@ ContentPoolTest:test_canBeDeployedAndInit_ok() (gas: 2820972) ContentPoolTest:test_getRewardStates_ok() (gas: 223662) ContentPoolTest:test_initialize_InitTwice_ko() (gas: 17982) ContentPoolTest:test_participantStates_ok() (gas: 220752) -ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428822) -ContentPoolTest:test_updateUserAndPool_ok() (gas: 325566) -ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539590) -ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713487) -ContentPoolTest:test_updateUser_ok() (gas: 400356) +ContentPoolTest:test_updateUserAndPool_WithRewardBeforeState_ok() (gas: 428709) +ContentPoolTest:test_updateUserAndPool_ok() (gas: 325512) +ContentPoolTest:test_updateUser_MultiTokenTransfer_ok() (gas: 539500) +ContentPoolTest:test_updateUser_WithRewardBeforeStateChange_ok() (gas: 713307) +ContentPoolTest:test_updateUser_ok() (gas: 400284) FrakTeasuryWalletTest:test_canBeDeployedAndInit_ok() (gas: 1773426) FrakTeasuryWalletTest:test_initialize_InitTwice_ko() (gas: 17937) FrakTeasuryWalletTest:test_transferBatch_InvalidArray_ko() (gas: 28753) FrakTeasuryWalletTest:test_transferBatch_NoReward_ko() (gas: 34416) -FrakTeasuryWalletTest:test_transferBatch_NotEnoughTreasury_ko() (gas: 11346454) +FrakTeasuryWalletTest:test_transferBatch_NotEnoughTreasury_ko() (gas: 11322694) FrakTeasuryWalletTest:test_transferBatch_NotMinter_ko() (gas: 18928) FrakTeasuryWalletTest:test_transferBatch_RewardTooLarge_ko() (gas: 34431) -FrakTeasuryWalletTest:test_transferBatch_ok() (gas: 137933) +FrakTeasuryWalletTest:test_transferBatch_ok() (gas: 137888) FrakTeasuryWalletTest:test_transfer_InvalidAddress_ko() (gas: 18375) FrakTeasuryWalletTest:test_transfer_NoReward_ko() (gas: 20508) -FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11345164) +FrakTeasuryWalletTest:test_transfer_NotEnoughTreasury_ko() (gas: 11321404) FrakTeasuryWalletTest:test_transfer_NotMinter_ko() (gas: 17684) FrakTeasuryWalletTest:test_transfer_RewardTooLarge_ko() (gas: 20534) -FrakTeasuryWalletTest:test_transfer_ok() (gas: 136171) -FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3433) +FrakTeasuryWalletTest:test_transfer_ok() (gas: 136126) +FrakTokenTest:invariant_cap_lt_supply() (runs: 256, calls: 3840, reverts: 3470) FrakTokenTest:test_burn_ok() (gas: 53321) -FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 4966458) +FrakTokenTest:test_canBeDeployedAndInit_ok() (gas: 4949212) FrakTokenTest:test_cap_ok() (gas: 10366) FrakTokenTest:test_decimals_ok() (gas: 10426) FrakTokenTest:test_initialize_InitTwice_ko() (gas: 15759) @@ -34,44 +34,44 @@ FrakTokenTest:test_mint_CapExceed_ko() (gas: 88431) FrakTokenTest:test_mint_InvalidRole_ko() (gas: 17704) FrakTokenTest:test_mint_ok() (gas: 68219) FrakTokenTest:test_name_ok() (gas: 14776) -FrakTokenTest:test_permit_DelayExpired_ko() (gas: 28069) -FrakTokenTest:test_permit_InvalidNonce_ko() (gas: 50313) -FrakTokenTest:test_permit_InvalidSigner_ko() (gas: 53922) -FrakTokenTest:test_permit_ok() (gas: 77759) -FrakTokenTest:test_symbol_ok() (gas: 14775) +FrakTokenTest:test_permit_DelayExpired_ko() (gas: 28091) +FrakTokenTest:test_permit_InvalidNonce_ko() (gas: 50335) +FrakTokenTest:test_permit_InvalidSigner_ko() (gas: 53944) +FrakTokenTest:test_permit_ok() (gas: 77781) +FrakTokenTest:test_symbol_ok() (gas: 14797) FraktionCostBadgesTest:test_defaultPrice_InvalidFraktionType_ko() (gas: 46597) FraktionCostBadgesTest:test_defaultPrice_ok() (gas: 26214) FraktionCostBadgesTest:test_updatePrice_InvalidFraktionType_ko() (gas: 46266) FraktionCostBadgesTest:test_updatePrice_InvalidRole_ko() (gas: 17661) FraktionCostBadgesTest:test_updatePrice_ok() (gas: 126566) -FraktionTokensTest:test_addContent_InvalidRole_ko() (gas: 18848) -FraktionTokensTest:test_addContent_SupplyUpdateNotAllowed_ko() (gas: 75153) -FraktionTokensTest:test_addContent_ok() (gas: 330020) +FraktionTokensTest:test_addContent_InvalidRole_ko() (gas: 18870) +FraktionTokensTest:test_addContent_SupplyUpdateNotAllowed_ko() (gas: 75241) +FraktionTokensTest:test_addContent_ok() (gas: 330174) FraktionTokensTest:test_batchBalance_ok() (gas: 59879) -FraktionTokensTest:test_burn_ok() (gas: 49561) -FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 7356977) +FraktionTokensTest:test_burn_ok() (gas: 49614) +FraktionTokensTest:test_canBeDeployedAndInit_ok() (gas: 7339660) FraktionTokensTest:test_initialize_InitTwice_ko() (gas: 16030) -FraktionTokensTest:test_ownerOf_ok() (gas: 16888) +FraktionTokensTest:test_ownerOf_ok() (gas: 16910) FraktionTokensTest:test_permitTransferAll_DelayExpired_ko() (gas: 27984) FraktionTokensTest:test_permitTransferAll_InvalidNonce_ko() (gas: 50430) FraktionTokensTest:test_permitTransferAll_InvalidSigner_ko() (gas: 53829) FraktionTokensTest:test_permitTransferAll_ok() (gas: 77652) -FraktionTokensTest:test_setUpTransferCallback_ok() (gas: 367334) -FraktionTokensTest:test_supply_InvalidRole_ko() (gas: 53411) -FraktionTokensTest:test_supply_SupplyUpdateNotAllowed_ko() (gas: 45910) -FraktionTokensTest:test_supply_ok() (gas: 87688) +FraktionTokensTest:test_setUpTransferCallback_ok() (gas: 367202) +FraktionTokensTest:test_supply_InvalidRole_ko() (gas: 53455) +FraktionTokensTest:test_supply_SupplyUpdateNotAllowed_ko() (gas: 45998) +FraktionTokensTest:test_supply_ok() (gas: 87798) FraktionTokensTest:test_transferAllFrom_ok() (gas: 189678) MinterTest:test_addContent_InvalidRole_ko() (gas: 17808) MinterTest:test_addContent_InvalidSupply_ko() (gas: 62459) -MinterTest:test_addContent_ok() (gas: 194423) -MinterTest:test_benchmarkAddContent_ok() (gas: 695381) +MinterTest:test_addContent_ok() (gas: 194533) +MinterTest:test_benchmarkAddContent_ok() (gas: 695513) MinterTest:test_canBeDeployedAndInit_ok() (gas: 2267698) -MinterTest:test_increaseSupply_InvalidRole_ko() (gas: 62382) -MinterTest:test_increaseSupply_ok() (gas: 75937) +MinterTest:test_increaseSupply_InvalidRole_ko() (gas: 62404) +MinterTest:test_increaseSupply_ok() (gas: 76003) MinterTest:test_initialize_InitTwice_ko() (gas: 22408) -MinterTest:test_mintFraktionForUser_ok() (gas: 212890) -MinterTest:test_mintFraktion_TooManyFraktion_ko() (gas: 216413) -MinterTest:test_mintFraktion_ok() (gas: 210349) +MinterTest:test_mintFraktionForUser_ok() (gas: 212912) +MinterTest:test_mintFraktion_TooManyFraktion_ko() (gas: 216435) +MinterTest:test_mintFraktion_ok() (gas: 210371) MinterTest:test_mintFreeFraktionForUser_ok() (gas: 60215) MinterTest:test_mintFreeFraktion_ExpectingOnlyFreeFraktion_ko() (gas: 40161) MinterTest:test_mintFreeFraktion_TooManyFraktion_ko() (gas: 66109) @@ -94,11 +94,11 @@ MultiVestingWalletsTest:test_createVest_ok() (gas: 209085) MultiVestingWalletsTest:test_decimals_ok() (gas: 10391) MultiVestingWalletsTest:test_initialize_InitTwice_ko() (gas: 18027) MultiVestingWalletsTest:test_name_ok() (gas: 12085) -MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233671) -MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228608) -MultiVestingWalletsTest:test_release_ok() (gas: 238074) +MultiVestingWalletsTest:test_releaseAllForUser_ok() (gas: 233626) +MultiVestingWalletsTest:test_releaseAll_ok() (gas: 228563) +MultiVestingWalletsTest:test_release_ok() (gas: 238029) MultiVestingWalletsTest:test_symbol_ok() (gas: 12117) -MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103766) +MultiVestingWalletsTest:test_transferReserve_ok() (gas: 103721) MultiVestingWalletsTest:test_transfer_InvalidAddress_ko() (gas: 208297) MultiVestingWalletsTest:test_transfer_InvalidUser_ko() (gas: 209500) MultiVestingWalletsTest:test_transfer_ok() (gas: 226492) @@ -114,34 +114,34 @@ RewarderConfigTest:test_updateListenerBadge_InvalidRole_ko() (gas: 17711) RewarderConfigTest:test_updateListenerBadge_ok() (gas: 46543) RewarderConfigTest:test_updateTpu_InvalidRole_ko() (gas: 15412) RewarderConfigTest:test_updateTpu_ok() (gas: 23775) -RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139421) +RewarderDirectPaymentTest:test_payCreatorDirectlyBatch() (gas: 139443) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_EmptyAmount_ko() (gas: 81351) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidArray_ko() (gas: 79575) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_InvalidRole_ko() (gas: 80462) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeAmount_ko() (gas: 81409) RewarderDirectPaymentTest:test_payCreatorDirectlyBatch_TooLargeArray_ko() (gas: 82898) -RewarderDirectPaymentTest:test_payUserDirectly() (gas: 111305) +RewarderDirectPaymentTest:test_payUserDirectly() (gas: 111260) RewarderDirectPaymentTest:test_payUserDirectly_InvalidAddress_ko() (gas: 77950) RewarderDirectPaymentTest:test_payUserDirectly_InvalidReward_ko() (gas: 88598) RewarderDirectPaymentTest:test_payUserDirectly_InvalidRole_ko() (gas: 79280) -RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105810) -RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212628) -RewarderTest:test_pay_FreeFraktion_ok() (gas: 191993) +RewarderDirectPaymentTest:test_payUserDirectly_NotEnoughBalance_ko() (gas: 105765) +RewarderTest:test_pay_ContentTypeImpact_ok() (gas: 212716) +RewarderTest:test_pay_FreeFraktion_ok() (gas: 191970) RewarderTest:test_pay_InvalidAddress_ko() (gas: 21620) RewarderTest:test_pay_InvalidArray_ko() (gas: 38041) -RewarderTest:test_pay_InvalidContent_ko() (gas: 56849) +RewarderTest:test_pay_InvalidContent_ko() (gas: 56871) RewarderTest:test_pay_InvalidRoles_ko() (gas: 21259) -RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367580) +RewarderTest:test_pay_PayedFraktions_LargeListenCounts_ok() (gas: 367557) RewarderTest:test_pay_PayedFraktions_TooMuchListenCounts_ko() (gas: 167427) -RewarderTest:test_pay_PayedFraktions_ok() (gas: 405494) +RewarderTest:test_pay_PayedFraktions_ok() (gas: 405426) RewarderTest:test_pay_TooLargeReward_ko() (gas: 231010) VestingWalletFactoryTest:test_canBeDeployedAndInit_ok() (gas: 2093328) VestingWalletFactoryTest:test_initialize_InitTwice_ko() (gas: 17926) -WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359100) -WalletMigratorTest:test_claimAllFounds_ok() (gas: 359248) -WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634747) -WalletMigratorTest:test_fullMigration_ok() (gas: 634048) +WalletMigratorTest:test_claimAllFoundsForUser_ok() (gas: 359098) +WalletMigratorTest:test_claimAllFounds_ok() (gas: 359246) +WalletMigratorTest:test_fullMigrationForUser_ok() (gas: 634767) +WalletMigratorTest:test_fullMigration_ok() (gas: 634068) WalletMigratorTest:test_migrateFrationsForUser_ok() (gas: 269269) WalletMigratorTest:test_migrateFrations_ok() (gas: 269384) -WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144683) -WalletMigratorTest:test_migrateFrk_ok() (gas: 144880) \ No newline at end of file +WalletMigratorTest:test_migrateFrkForUser_ok() (gas: 144705) +WalletMigratorTest:test_migrateFrk_ok() (gas: 144902) \ No newline at end of file diff --git a/contracts/utils/EIP712Diamond.sol b/contracts/utils/EIP712Diamond.sol index b93363c..5d9e9c3 100644 --- a/contracts/utils/EIP712Diamond.sol +++ b/contracts/utils/EIP712Diamond.sol @@ -74,11 +74,6 @@ contract EIP712Diamond { return _getEIP712Storage()._nonces[user]; } - /// @dev Use the current 'nonce' for the given 'user' (and increment it) - function useNonce(address user) public returns (uint256) { - return _getEIP712Storage()._nonces[user]++; - } - /* -------------------------------------------------------------------------- */ /* Internal functions */ /* -------------------------------------------------------------------------- */ @@ -102,4 +97,9 @@ contract EIP712Diamond { mstore(0x3a, 0) } } + + /// @dev Use the current 'nonce' for the given 'user' (and increment it) + function useNonce(address user) internal returns (uint256) { + return _getEIP712Storage()._nonces[user]++; + } } diff --git a/package.json b/package.json index c34c245..aa86cda 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,8 @@ }, "devDependencies": { "@lcov-viewer/cli": "^1.3.0", - "@openzeppelin/upgrades-core": "^1.28.0", - "@wagmi/cli": "^1.4.1", + "@openzeppelin/upgrades-core": "^1.30.1", + "@wagmi/cli": "^1.5.2", "ts-node": "^10.9.1", "typescript": "^5.2.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4c5dcb7..d5efe80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,22 +9,22 @@ devDependencies: specifier: ^1.3.0 version: 1.3.0 '@openzeppelin/upgrades-core': - specifier: ^1.28.0 - version: 1.28.0 + specifier: ^1.30.1 + version: 1.30.1 '@wagmi/cli': - specifier: ^1.4.1 - version: 1.4.1(typescript@5.2.2) + specifier: ^1.5.2 + version: 1.5.2(typescript@5.2.2) ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.5.7)(typescript@5.2.2) + version: 10.9.1(@types/node@20.8.7)(typescript@5.2.2) typescript: specifier: ^5.2.2 version: 5.2.2 packages: - /@adraffy/ens-normalize@1.9.0: - resolution: {integrity: sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ==} + /@adraffy/ens-normalize@1.9.4: + resolution: {integrity: sha512-UK0bHA7hh9cR39V+4gl2/NnBBjoXIxkuWAPCaY4X7fbH4L/azIi7ilWOCjMUYfpJgraLUAqkRi2BqrjME8Rynw==} dev: true /@cspotcode/source-map-support@0.8.1: @@ -255,24 +255,14 @@ packages: commander: 9.5.0 dev: true - /@noble/curves@1.0.0: - resolution: {integrity: sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==} + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} dependencies: - '@noble/hashes': 1.3.0 + '@noble/hashes': 1.3.2 dev: true - /@noble/curves@1.1.0: - resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} - dependencies: - '@noble/hashes': 1.3.1 - dev: true - - /@noble/hashes@1.3.0: - resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} - dev: true - - /@noble/hashes@1.3.1: - resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} dev: true @@ -297,8 +287,8 @@ packages: fastq: 1.15.0 dev: true - /@openzeppelin/upgrades-core@1.28.0: - resolution: {integrity: sha512-8RKlyg98Adv+46GxDaR0awL3R8bVCcQ27DcSEwrgWOp6siHh8sZg4a2l+2dhPl1510S6uBfhHSydMH5VX2BV5g==} + /@openzeppelin/upgrades-core@1.30.1: + resolution: {integrity: sha512-mFUsZibpiWJv1DR2K89cjbFIseTc2CUV4D2kvPPK5xYke6m7+M87qcr/Xk24mMrdCmG7RWNxQohhVnzESI6Eeg==} hasBin: true dependencies: cbor: 9.0.1 @@ -317,18 +307,18 @@ packages: resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} dev: true - /@scure/bip32@1.3.0: - resolution: {integrity: sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q==} + /@scure/bip32@1.3.2: + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} dependencies: - '@noble/curves': 1.0.0 - '@noble/hashes': 1.3.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 '@scure/base': 1.1.3 dev: true - /@scure/bip39@1.2.0: - resolution: {integrity: sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg==} + /@scure/bip39@1.2.1: + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} dependencies: - '@noble/hashes': 1.3.0 + '@noble/hashes': 1.3.2 '@scure/base': 1.1.3 dev: true @@ -348,47 +338,32 @@ packages: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} dev: true - /@types/bn.js@5.1.1: - resolution: {integrity: sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==} + /@types/bn.js@5.1.3: + resolution: {integrity: sha512-wT1B4iIO82ecXkdN6waCK8Ou7E71WU+mP1osDA5Q8c6Ur+ozU2vIKUIhSpUr6uE5L2YHocKS1Z2jG2fBC1YVeg==} dependencies: - '@types/node': 20.5.7 + '@types/node': 20.8.7 dev: true - /@types/node@20.5.7: - resolution: {integrity: sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==} - dev: true - - /@types/pbkdf2@3.1.0: - resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} + /@types/node@20.8.7: + resolution: {integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==} dependencies: - '@types/node': 20.5.7 + undici-types: 5.25.3 dev: true - /@types/secp256k1@4.0.3: - resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} + /@types/pbkdf2@3.1.1: + resolution: {integrity: sha512-4HCoGwR3221nOc7G0Z/6KgTNGgaaFGkbGrtUJsB+zlKX2LBVjFHHIUkieMBgHHXgBH5Gq6dZHJKdBYdtlhBQvw==} dependencies: - '@types/node': 20.5.7 + '@types/node': 20.8.7 dev: true - /@types/ws@8.5.5: - resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} + /@types/secp256k1@4.0.5: + resolution: {integrity: sha512-aIonTBMErtE3T9MxDvTZRzcrT/mCqpEZBw3CCY/i+oG9n57N/+7obBkhFgavUAIrX21bU0LHg1XRgtaLdelBhA==} dependencies: - '@types/node': 20.5.7 + '@types/node': 20.8.7 dev: true - /@wagmi/chains@1.8.0(typescript@5.2.2): - resolution: {integrity: sha512-UXo0GF0Cl0+neKC2KAmVAahv8L/5rACbFRRqkDvHMefzY6Fh7yzJd8F4GaGNNG3w4hj8eUB/E3+dEpaTYDN62w==} - peerDependencies: - typescript: '>=5.0.4' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - typescript: 5.2.2 - dev: true - - /@wagmi/cli@1.4.1(typescript@5.2.2): - resolution: {integrity: sha512-Et9ni95ewmN+SCJaPEX16681hvALlXKda5QjDzDgX9tPyy560GOvUZY+mYgU1EEOiSO1ONt2We20C7YhtYwLRQ==} + /@wagmi/cli@1.5.2(typescript@5.2.2): + resolution: {integrity: sha512-UfLMYhW6mQBCjR8A5s01Chf9GpHzdpcuuBuzJ36QGXcMSJAxylz5ImVZWfCRV0ct1UruydjKVSW1QSI6azNxRQ==} engines: {node: '>=14'} hasBin: true peerDependencies: @@ -403,8 +378,7 @@ packages: wagmi: optional: true dependencies: - '@wagmi/chains': 1.8.0(typescript@5.2.2) - abitype: 0.8.7(typescript@5.2.2)(zod@3.22.2) + abitype: 0.8.7(typescript@5.2.2)(zod@3.22.4) abort-controller: 3.0.0 bundle-require: 3.1.2(esbuild@0.16.17) cac: 6.7.14 @@ -425,14 +399,14 @@ packages: picocolors: 1.0.0 prettier: 2.8.8 typescript: 5.2.2 - viem: 1.9.3(typescript@5.2.2)(zod@3.22.2) - zod: 3.22.2 + viem: 1.16.6(typescript@5.2.2)(zod@3.22.4) + zod: 3.22.4 transitivePeerDependencies: - bufferutil - utf-8-validate dev: true - /abitype@0.8.7(typescript@5.2.2)(zod@3.22.2): + /abitype@0.8.7(typescript@5.2.2)(zod@3.22.4): resolution: {integrity: sha512-wQ7hV8Yg/yKmGyFpqrNZufCxbszDe5es4AZGYPBitocfSqXtjrTG9JMWFcc4N30ukl2ve48aBTwt7NJxVQdU3w==} peerDependencies: typescript: '>=5.0.4' @@ -442,11 +416,11 @@ packages: optional: true dependencies: typescript: 5.2.2 - zod: 3.22.2 + zod: 3.22.4 dev: true - /abitype@0.9.3(typescript@5.2.2)(zod@3.22.2): - resolution: {integrity: sha512-dz4qCQLurx97FQhnb/EIYTk/ldQ+oafEDUqC0VVIeQS1Q48/YWt/9YNfMmp9SLFqN41ktxny3c8aYxHjmFIB/w==} + /abitype@0.9.8(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ==} peerDependencies: typescript: '>=5.0.4' zod: ^3 >=3.19.1 @@ -457,7 +431,7 @@ packages: optional: true dependencies: typescript: 5.2.2 - zod: 3.22.2 + zod: 3.22.4 dev: true /abort-controller@3.0.0: @@ -505,7 +479,7 @@ packages: /array-buffer-byte-length@1.0.0: resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 is-array-buffer: 3.0.2 dev: true @@ -513,21 +487,22 @@ packages: resolution: {integrity: sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 - es-shim-unscopables: 1.0.0 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.2 + get-intrinsic: 1.2.2 dev: true - /arraybuffer.prototype.slice@1.0.1: - resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - call-bind: 1.0.2 - define-properties: 1.2.0 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 is-array-buffer: 3.0.2 is-shared-array-buffer: 1.0.2 dev: true @@ -634,11 +609,12 @@ packages: engines: {node: '>=8'} dev: true - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.1 + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 dev: true /camel-case@4.1.2: @@ -722,8 +698,8 @@ packages: restore-cursor: 4.0.0 dev: true - /cli-spinners@2.9.0: - resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==} + /cli-spinners@2.9.1: + resolution: {integrity: sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==} engines: {node: '>=6'} dev: true @@ -821,11 +797,21 @@ packages: clone: 1.0.4 dev: true - /define-properties@1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - has-property-descriptors: 1.0.0 + define-data-property: 1.1.1 + has-property-descriptors: 1.0.1 object-keys: 1.1.1 dev: true @@ -877,26 +863,26 @@ packages: minimalistic-crypto-utils: 1.0.1 dev: true - /es-abstract@1.22.1: - resolution: {integrity: sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==} + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.1 + arraybuffer.prototype.slice: 1.0.2 available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 get-symbol-description: 1.0.0 globalthis: 1.0.3 gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 + has-property-descriptors: 1.0.1 has-proto: 1.0.1 has-symbols: 1.0.3 - internal-slot: 1.0.5 + hasown: 2.0.0 + internal-slot: 1.0.6 is-array-buffer: 3.0.2 is-callable: 1.2.7 is-negative-zero: 2.0.2 @@ -905,36 +891,36 @@ packages: is-string: 1.0.7 is-typed-array: 1.1.12 is-weakref: 1.0.2 - object-inspect: 1.12.3 + object-inspect: 1.13.1 object-keys: 1.1.1 object.assign: 4.1.4 - regexp.prototype.flags: 1.5.0 - safe-array-concat: 1.0.0 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 safe-regex-test: 1.0.0 - string.prototype.trim: 1.2.7 - string.prototype.trimend: 1.0.6 - string.prototype.trimstart: 1.0.6 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 typed-array-buffer: 1.0.0 typed-array-byte-length: 1.0.0 typed-array-byte-offset: 1.0.0 typed-array-length: 1.0.4 unbox-primitive: 1.0.2 - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + /es-set-tostringtag@2.0.2: + resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.3 + get-intrinsic: 1.2.2 has-tostringtag: 1.0.0 + hasown: 2.0.0 dev: true - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: - has: 1.0.3 + hasown: 2.0.0 dev: true /es-to-primitive@1.2.1: @@ -979,15 +965,15 @@ packages: /ethereum-cryptography@0.1.3: resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} dependencies: - '@types/pbkdf2': 3.1.0 - '@types/secp256k1': 4.0.3 + '@types/pbkdf2': 3.1.1 + '@types/secp256k1': 4.0.5 blakejs: 1.2.1 browserify-aes: 1.2.0 bs58check: 2.1.2 create-hash: 1.2.0 create-hmac: 1.1.7 hash.js: 1.1.7 - keccak: 3.0.3 + keccak: 3.0.4 pbkdf2: 3.1.2 randombytes: 2.1.0 safe-buffer: 5.2.1 @@ -1000,7 +986,7 @@ packages: resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} engines: {node: '>=10.0.0'} dependencies: - '@types/bn.js': 5.1.1 + '@types/bn.js': 5.1.3 bn.js: 5.2.1 create-hash: 1.2.0 ethereum-cryptography: 0.1.3 @@ -1119,17 +1105,17 @@ packages: dev: true optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 functions-have-names: 1.2.3 dev: true @@ -1137,13 +1123,13 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: - function-bind: 1.1.1 - has: 1.0.3 + function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 + hasown: 2.0.0 dev: true /get-stream@6.0.1: @@ -1155,8 +1141,8 @@ packages: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 dev: true /glob-parent@5.1.2: @@ -1170,7 +1156,7 @@ packages: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} dependencies: - define-properties: 1.2.0 + define-properties: 1.2.1 dev: true /globby@13.2.2: @@ -1187,7 +1173,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /graceful-fs@4.2.11: @@ -1203,10 +1189,10 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.1: + resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.1 + get-intrinsic: 1.2.2 dev: true /has-proto@1.0.1: @@ -1226,13 +1212,6 @@ packages: has-symbols: 1.0.3 dev: true - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: true - /hash-base@3.1.0: resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} engines: {node: '>=4'} @@ -1249,6 +1228,13 @@ packages: minimalistic-assert: 1.0.1 dev: true + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: true + /header-case@2.0.4: resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} dependencies: @@ -1287,20 +1273,20 @@ packages: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: true - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + /internal-slot@1.0.6: + resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.1 - has: 1.0.3 + get-intrinsic: 1.2.2 + hasown: 2.0.0 side-channel: 1.0.4 dev: true /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -1321,7 +1307,7 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true @@ -1375,14 +1361,14 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-tostringtag: 1.0.0 dev: true /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /is-stream@2.0.1: @@ -1413,7 +1399,7 @@ packages: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.11 + which-typed-array: 1.1.13 dev: true /is-unicode-supported@1.3.0: @@ -1424,7 +1410,7 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 dev: true /isarray@2.0.5: @@ -1435,12 +1421,12 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true - /isomorphic-ws@5.0.0(ws@8.12.0): - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + /isows@1.0.3(ws@8.13.0): + resolution: {integrity: sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==} peerDependencies: ws: '*' dependencies: - ws: 8.12.0 + ws: 8.13.0 dev: true /jsonfile@6.1.0: @@ -1451,8 +1437,8 @@ packages: graceful-fs: 4.2.11 dev: true - /keccak@3.0.3: - resolution: {integrity: sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==} + /keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} engines: {node: '>=10.0.0'} requiresBuild: true dependencies: @@ -1596,8 +1582,8 @@ packages: path-key: 4.0.0 dev: true - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} dev: true /object-keys@1.1.1: @@ -1609,8 +1595,8 @@ packages: resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 + call-bind: 1.0.5 + define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 dev: true @@ -1635,7 +1621,7 @@ packages: dependencies: chalk: 5.3.0 cli-cursor: 4.0.0 - cli-spinners: 2.9.0 + cli-spinners: 2.9.1 is-interactive: 2.0.0 is-unicode-supported: 1.3.0 log-symbols: 5.1.0 @@ -1763,13 +1749,13 @@ packages: picomatch: 2.3.1 dev: true - /regexp.prototype.flags@1.5.0: - resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - functions-have-names: 1.2.3 + call-bind: 1.0.5 + define-properties: 1.2.1 + set-function-name: 2.0.1 dev: true /restore-cursor@4.0.0: @@ -1810,12 +1796,12 @@ packages: queue-microtask: 1.2.3 dev: true - /safe-array-concat@1.0.0: - resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -1827,8 +1813,8 @@ packages: /safe-regex-test@1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-regex: 1.1.4 dev: true @@ -1854,6 +1840,25 @@ packages: upper-case-first: 2.0.2 dev: true + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.1 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.1 + dev: true + /setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} dev: true @@ -1881,9 +1886,9 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 - object-inspect: 1.12.3 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + object-inspect: 1.13.1 dev: true /signal-exit@3.0.7: @@ -1915,29 +1920,29 @@ packages: bl: 5.1.0 dev: true - /string.prototype.trim@1.2.7: - resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 dev: true - /string.prototype.trimend@1.0.6: - resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 dev: true - /string.prototype.trimstart@1.0.6: - resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.22.1 + call-bind: 1.0.5 + define-properties: 1.2.1 + es-abstract: 1.22.3 dev: true /string_decoder@1.3.0: @@ -1977,7 +1982,7 @@ packages: is-number: 7.0.0 dev: true - /ts-node@10.9.1(@types/node@20.5.7)(typescript@5.2.2): + /ts-node@10.9.1(@types/node@20.8.7)(typescript@5.2.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -1996,7 +2001,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.5.7 + '@types/node': 20.8.7 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -2016,8 +2021,8 @@ packages: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.1 + call-bind: 1.0.5 + get-intrinsic: 1.2.2 is-typed-array: 1.1.12 dev: true @@ -2025,7 +2030,7 @@ packages: resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -2036,7 +2041,7 @@ packages: engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 has-proto: 1.0.1 is-typed-array: 1.1.12 @@ -2045,7 +2050,7 @@ packages: /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 is-typed-array: 1.1.12 dev: true @@ -2059,12 +2064,16 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.5 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 dev: true + /undici-types@5.25.3: + resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==} + dev: true + /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} @@ -2090,24 +2099,23 @@ packages: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true - /viem@1.9.3(typescript@5.2.2)(zod@3.22.2): - resolution: {integrity: sha512-5NcxPHkWCZIBYm8A8oOd77l2RQ/+VRm1p56mBxoRcZ+Mij5pA+5Y3cohz7MHt6gYmmoDWlLXUXxsdPLedeF2wg==} + /viem@1.16.6(typescript@5.2.2)(zod@3.22.4): + resolution: {integrity: sha512-jcWcFQ+xzIfDwexwPJRvCuCRJKEkK9iHTStG7mpU5MmuSBpACs4nATBDyXNFtUiyYTFzLlVEwWkt68K0nCSImg==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: typescript: optional: true dependencies: - '@adraffy/ens-normalize': 1.9.0 - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.0 - '@scure/bip32': 1.3.0 - '@scure/bip39': 1.2.0 - '@types/ws': 8.5.5 - abitype: 0.9.3(typescript@5.2.2)(zod@3.22.2) - isomorphic-ws: 5.0.0(ws@8.12.0) + '@adraffy/ens-normalize': 1.9.4 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 0.9.8(typescript@5.2.2)(zod@3.22.4) + isows: 1.0.3(ws@8.13.0) typescript: 5.2.2 - ws: 8.12.0 + ws: 8.13.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -2135,12 +2143,12 @@ packages: is-symbol: 1.0.4 dev: true - /which-typed-array@1.1.11: - resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} engines: {node: '>= 0.4'} dependencies: available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + call-bind: 1.0.5 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.0 @@ -2154,8 +2162,8 @@ packages: isexe: 2.0.0 dev: true - /ws@8.12.0: - resolution: {integrity: sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==} + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -2177,6 +2185,6 @@ packages: engines: {node: '>=12.20'} dev: true - /zod@3.22.2: - resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: true